Composable Predicates with the &, |, ~ Operators in Python
Define a reusable Predicate class that combines boolean checks with & (AND), | (OR), and ~ (NOT) operators.
Python code
33 linesclass Predicate:
def __init__(self, func, name=None):
self.func = func
self.name = name or getattr(func, "__name__", "predicate")
def __call__(self, value):
return self.func(value)
def __and__(self, other):
return Predicate(lambda v: self(v) and other(v), f"({self.name} AND {other.name})")
def __or__(self, other):
return Predicate(lambda v: self(v) or other(v), f"({self.name} OR {other.name})")
def __invert__(self):
return Predicate(lambda v: not self(v), f"(NOT {self.name})")
def __repr__(self):
return self.name
is_even = Predicate(lambda n: n % 2 == 0, "is_even")
is_positive = Predicate(lambda n: n > 0, "is_positive")
is_small = Predicate(lambda n: n < 10, "is_small")
is_positive_even = is_even & is_positive
is_small_or_negative_even = is_small | (~is_positive)
if __name__ == "__main__":
values = [0, 2, 5, -4, 12, 7]
print("Predicates:", is_positive_even, "and", is_small_or_negative_even)
for v in values:
print(v, "->", is_positive_even(v), is_small_or_negative_even(v))
Output
Predicates: (is_even AND is_positive) and (is_small OR (NOT is_positive))
0 -> False False
2 -> True False
5 -> False True
-4 -> False True
12 -> True False
7 -> False True
How it works
This class wraps a function in a callable object and implements __and__, __or__, and __invert__ so Python's &, |, and ~ operators work as logical AND, OR, and NOT. Each operation returns a new Predicate, keeping the original predicates untouched and enabling chains like a & b | c. The name parameter provides readable labels used in repr, which makes debugging and logging much easier.
Common mistakes
- Forgetting that `and`/`or` cannot be overloaded; you must use `&`/`|`.
- Modifying the original predicate when chaining; always return a new instance.
- Not preserving the function name as a fallback display name.
Variations
- Use `functools.partial` or a decorator to create predicate factories without a class.
- Implement `__and__` etc. to accept other callables, not just Predicate instances.
Real-world use cases
- Build a rules engine that combines eligibility checks with AND/OR without nested if-statements.
- Filter a large dataset using composable criteria, e.g., in a data pipeline or query builder.
- Express complex feature flags as reusable, combinable conditions in a microservice.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
- Compute Derived Fields with @dataclass __post_init__ in Python easy
Keep learning
Related tutorials and quizzes for this topic.