Python logic slows to a crawl; policy pattern offers a way out
The Trap of Growing Conditionals
Software decay often begins with a single if statement. What starts as a simple check for an active user inevitably spirals into a tangled mess of nested flags, role checks, and audit logging. While this code technically works, it fails the scalability test. Adding a new business rule requires modifying a massive, central function, which increases the surface area for bugs and makes unit testing a nightmare. This architectural bottleneck is exactly what the aims to resolve by decomposing monolithic logic into isolated, single-responsibility rules.
Prerequisites
To implement this pattern effectively, you should be comfortable with fundamentals, particularly type hinting and data classes. Familiarity with higher-order functions like reduce and a basic understanding of object-oriented principles versus functional programming will help you choose the right implementation style for your specific codebase.
Key Libraries & Tools

- dataclasses: Used for creating lightweight, immutable-like data structures to hold user and request state.
- : A library for managing environment-variable-driven configuration, allowing you to toggle policies without changing code.
- functools.reduce: A functional tool used to chain multiple policy functions together into a single execution pipeline.
- typing.Protocol: Used in the OOP approach to define structural subtyping for policy classes.
Refactoring to Functional Pipelines
While an OOP approach uses classes and protocols, a implementation often leans on functional composition. Instead of a giant function, we define individual policy functions that take a user and a request, returning a modified request object.
def active_user_policy(user: User, request: Request) -> Request:
if not user.is_active:
raise PermissionError("Inactive user")
return request
def audit_policy(user: User, request: Request) -> Request:
return replace(request, audit_log=request.audit_log + ["Audited"])
By ensuring every function returns the request, we can use reduce to fold a list of these functions over our initial data. This transforms our logic into a clear, linear pipeline where the order of operations is explicit and easily modified.
Syntax Notes
- Data Class Replace: Using
dataclasses.replaceis preferred over direct mutation to maintain a pseudo-immutable flow through the pipeline. - Lambda Reducers: The
reduce(lambda current, policy: policy(user, current), policies, initial_request)pattern is a powerful way to execute a sequence of transformations on a single object.
Practical Examples
In a production environment, this pattern shines when integrated with a configuration layer. By mapping strings in a .env file to a policy registry (a simple dictionary), you can enable or disable features like multi-factor authentication or specialized auditing per environment without redeploying code. This effectively turns your policies into high-granularity feature flags.
Tips & Gotchas
Avoid over-engineering throwaway scripts with this pattern; it is designed for complex, evolving systems. Be mindful of the execution order in your pipeline, as policies earlier in the list can prevent later policies from running if they raise exceptions. Always keep your policy functions pure to ensure they remain easy to test in isolation.
- 17%· products
- 17%· programming
- 17%· products
- 17%· programming
- 17%· programming
- 17%· programming

Don’t Use Boolean Flags in Python, Use Policies Instead
WatchArjanCodes // 15:10
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!