Inference is straightforward using dictionaries, membership-testing, and set methods, like subset, superset, disjoint, union, intersection, and difference.
Python can't do a conditional assignment as nicely as Prolog's unification, but you can get similar behavior via the application of predicates in comprehensions and using set methods. I'm not saying Python is equivalent, but simply that you can get some of Prolog's style in Python. Erlang's pattern matching and concept of bound vs unbound variables is a bit closer to Prolog's unification.
Here's some Python implementations for examples shown in my first Google result for "prolog examples" (http://www.cs.toronto.edu/~sheila/384/w11/simple-prolog-exam...)
1. Here are some simple clauses.
>>> likes = {'mary': {'food', 'wine'},
... 'john': {'wine', 'mary'}}
>>> 'food' in likes['mary']
True
>>> 'wine' in likes['john']
True
>>> 'food' in likes['john']
False
>>> # John likes anything that Mary likes
>>> likes['john'] |= likes['mary']
>>> # John likes anyone who likes wine
>>> likes['john'] |= {name for name, objs likes.items() if 'wine' in objs}
>>> # John likes anyone who likes themselves
>>> likes['john'] |= {name for name, objs in likes.items() if name in objs}
2. Slightly more complicated family tree.
>>> male = {'james1', 'charles1', 'charles2', 'james2', 'george1'}
>>> female = {'catherine', 'elizabeth', 'sophia'}
>>> parents = {'charles1': 'james1',
... 'elizabeth': 'james1',
... 'charles2': 'charles1',
... 'catherine': 'charles1',
... 'james2': 'charles1',
... 'sophia': 'elizabeth',
... 'george1': 'sophia'}
>>> # Was George I the parent of Charles I?
>>> parents['charles1'] == 'george1'
False
>>> # Who was Charles I's parent?
>>> parents['charles1']
'james1'
>>> # Who were the children of Charles I?
>>> {child for child, parent in parents.items() if parent == 'charles1'}
{'charles2', 'james2', 'catherine'}
3. Recursion: Towers of Hanoi
>>> def move_one(x, y):
... print('Move top disk from {0} to {1}'.format(x, y))
... return True
...
>>> def move(n, x, y, z):
... if n == 1:
... return move_one(x, y)
... m = n - 1
... move(m, x, z, y)
... move_one(x, y)
... return move(m, z, y, x)
...
>>> move(3, 'left', 'right', 'center')
Move top disk from left to right
Move top disk from left to center
Move top disk from right to center
Move top disk from left to right
Move top disk from center to left
Move top disk from center to right
Move top disk from left to right
True
4. An example using lists:
This last one is a bit silly in Python as all the tools shown are built-ins.