zedr / clean-code-python
:bathtub: Clean Code concepts adapted for Python
AI Architecture Analysis
This repository is indexed by RepoMind. By analyzing zedr/clean-code-python in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.
Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.
Repository Overview (README excerpt)
Crawler viewclean-code-python Table of Contents • Introduction • Variables • Functions • Classes • S: Single Responsibility Principle (SRP) • O: Open/Closed Principle (OCP) • L: Liskov Substitution Principle (LSP) • I: Interface Segregation Principle (ISP) • D: Dependency Inversion Principle (DIP) • Don't repeat yourself (DRY) • Translations Introduction Software engineering principles, from Robert C. Martin's book *Clean Code* , adapted for Python. This is not a style guide. It's a guide to producing readable, reusable, and refactorable software in Python. Not every principle herein has to be strictly followed, and even fewer will be universally agreed upon. These are guidelines and nothing more, but they are ones codified over many years of collective experience by the authors of *Clean Code*. Adapted from clean-code-javascript Targets Python3.7+ **Variables** Use meaningful and pronounceable variable names **Bad:** Additionally, there's no need to add the type of the variable (str) to its name. **Good**: **⬆ back to top** Use the same vocabulary for the same type of variable **Bad:** Here we use three different names for the same underlying entity: **Good**: If the entity is the same, you should be consistent in referring to it in your functions: **Even better** Python is (also) an object oriented programming language. If it makes sense, package the functions together with the concrete implementation of the entity in your code, as instance attributes, property methods, or methods: **⬆ back to top** Use searchable names We will read more code than we will ever write. It's important that the code we do write is readable and searchable. By *not* naming variables that end up being meaningful for understanding our program, we hurt our readers. Make your names searchable. **Bad:** **Good**: **⬆ back to top** Use explanatory variables **Bad:** **Not bad**: It's better, but we are still heavily dependent on regex. **Good**: Decrease dependence on regex by naming subpatterns. **⬆ back to top** Avoid Mental Mapping Don’t force the reader of your code to translate what the variable means. Explicit is better than implicit. **Bad:** **Good**: **⬆ back to top** Don't add unneeded context If your class/object name tells you something, don't repeat that in your variable name. **Bad:** **Good**: **⬆ back to top** Use default arguments instead of short circuiting or conditionals **Tricky** Why write: ... when you can specify a default argument instead? This also makes it clear that you are expecting a string as the argument. **Good**: **⬆ back to top** **Functions** Functions should do one thing This is by far the most important rule in software engineering. When functions do more than one thing, they are harder to compose, test, and reason about. When you can isolate a function to just one action, they can be refactored easily and your code will read much cleaner. If you take nothing else away from this guide other than this, you'll be ahead of many developers. **Bad:** **Good**: Do you see an opportunity for using generators now? **Even better** **⬆ back to top** Function arguments (2 or fewer ideally) A large amount of parameters is usually the sign that a function is doing too much (has more than one responsibility). Try to decompose it into smaller functions having a reduced set of parameters, ideally less than three. If the function has a single responsibility, consider if you can bundle some or all parameters into a specialized object that will be passed as an argument to the function. These parameters might be attributes of a single entity that you can represent with a dedicated data structure. You may also be able to reuse this entity elsewhere in your program. The reason why this is a better arrangement is than having multiple parameters is that we may be able to move some computations, done with those parameters inside the function, into methods belonging to the new object, therefore reducing the complexity of the function. **Bad:** **Java-esque**: **Also good** **Fancy** **Even fancier** **Even fancier, Python3.8+ only** **⬆ back to top** Function names should say what they do **Bad:** **Good:** **⬆ back to top** Functions should only be one level of abstraction When you have more than one level of abstraction, your function is usually doing too much. Splitting up functions leads to reusability and easier testing. **Bad:** **Good:** **⬆ back to top** Don't use flags as function parameters Flags tell your user that this function does more than one thing. Functions should do one thing. Split your functions if they are following different code paths based on a boolean. **Bad:** **Good:** **⬆ back to top** Avoid side effects A function produces a side effect if it does anything other than take a value in and return another value or values. For example, a side effect could be writing to a file, modifying some global variable, or accidentally wiring all your money to a stranger. Now, you do need to have side effects in a program on occasion - for example, like in the previous example, you might need to write to a file. In these cases, you should centralize and indicate where you are incorporating side effects. Don't have several functions and classes that write to a particular file - rather, have one (and only one) service that does it. The main point is to avoid common pitfalls like sharing state between objects without any structure, using mutable data types that can be written to by anything, or using an instance of a class, and not centralizing where your side effects occur. If you can do this, you will be happier than the vast majority of other programmers. **Bad:** **Good:** **Also good** **⬆ back to top** **Classes** **Single Responsibility Principle (SRP)** Robert C. Martin writes: > A class should have only one reason to change. "Reasons to change" are, in essence, the responsibilities managed by a class or fun…