This is a collection of best practices and anti-patterns for Python and popular Python frameworks, such as Django, Flask or Odoo. Explore the different sections of this knowledge base, to increase the correctness, security, performance, maintainability, and readability of your Python code. Sign up for free to automatically monitor whether your own projects comply with all these best practices.
You can also explore the code quality of over 5.000 open source projects for free and contribute to this collection by creating or suggesting your own articles.
Python
Correctness
Assigning to built-in exception
Avoid accessing protected class members from outside
Avoid calling magic methods
Avoid calling uncallable object
Avoid concatenating different built-in types
Avoid deprecated string functions
Avoid empty exception handlers
Avoid infinite loops
Avoid misleading chained comparisons
Avoid multiple function return types
Avoid mutable default arguments
Avoid overwriting built-in functions/attributes
Avoid re-definition of unused name
Avoid repetitive element assignment
Avoid unreachable except clauses
Avoid untyped exception handlers
Avoid unused arguments
Avoid using
+=for concatenation of non-local listsAvoid whitespaces in your replacement field names
break/continueoutside loopCall
__init__method from base classCheck assignment to
TrueorFalseCheck
__init__method call, from a non-direct base classCheck overload of built-in function
Check undefined name in
__all__Class has no member
Consider using
defaultdict()to set default valuesDo not redefine name from outer scope
Don't hide methods via attributes
Don't overload modules with loop variables
Don't redefine names through list comprehensions
Don't use
__init__methods as generatorDon't use undefined loop variable
Don't use undefined name
Duplicate argument name in function definition
Duplicate key in dictionary
elseclause on a loop without abreakstatementEnsure child class signature matches parent class implementation
__exit__function has the wrong signatureFirst argument of a classmethod should be called
cls__future__import is not the first real statement in a moduleImport naming collision
Inherit from
BaseExceptionfor all custom exceptionsLocal variable assigned but never used
Match function call with function signature
Match number of replacement fields to
format()argumentsMethod is abstract in class but is not overridden
NotImplementedraised, instead ofNotImplementedErrorNumber replacement fields consistently
object.__members__deprecatedOnly raise valid exception types
opencalled with invalid mode stringParameter passed as both positional and keyword argument
Pass correct number of positional arguments to function call
Passing unexpected keyword argument in function call
Provide argument or
@staticmethodto methodRemove unreachable code
Returning a value from
__init__Return iterator in
__iter__to avoid runtime errorsreturnstatement outside of a functionUse child class name as first argument to
supercallUse correct import name from module
Use
else-clause in for-loopUse new-style Python classes
Use relative imports
yieldstatement outside of a function or method
Maintainability
Ask for permission instead of forgiveness
Avoid consecutive if-statements
Avoid deprecated
<>operatorAvoid manually cloning a list
Avoid "non-Pythonic" method names
Avoid temporary
kwargsAvoid using intermediate variables whenever possible
Avoid using Java style dicts
Avoid using
len(x)to check if x is emptyAvoid using "non-Pythonic" function names
Avoid using "non-Pythonic" variable names
Avoid using range() of len() to get index of iterable
Avoid using the
globalstatementAvoid using
.update()to create merged dictionariesAvoid using wildcard (*) imports
Consider documenting your class(es)
Consider documenting your function(s)
Consider simplifying bounds checks
Consider simplifying out-of-bounds checks
Consider splitting your assert statements
Consider using 'mpl' as alias for matplotlib imports
Consider using 'np' as alias for numpy imports
Consider using 'pd' as alias for pandas imports
Consider using 'plt' as alias for matplotlib.pyplot imports
Consider using 'sns' as alias for seaborn imports
Consider using 'sp' as alias for scipy imports
dict.has_key()deprecatedDouble-check published secret key
Module name not matching naming conventions
object.__methods__deprecatedPrefer explicitly numbering replacement fields in a format string
Prefer
format()over%for string interpolationTry to start test methods with "test_"
Use constants as default values for arguments
Use dump instead of dumps for json files
Use
isinstance()to check for typeUse load instead of loads for json files
Use
@propertyinstead of Java-style of setter/getter methodsUse tuple as 2nd argument of
isinstance()to avoid repetitionUse
.update()instead of setting keys individuallyUsing the
globalstatement is unnecessary at module level.xreadlines()deprecated
Performance
Avoid nested loop joins
Avoid using C-style increment or decrement operators
Consider an iterator instead of materializing the inner list
Consider an iterator instead of materializing the list
Consider literals instead of
dict()constructor to initialize dictionariesConsider using a dict comprehension instead
dict(...)Consider using a set comprehensions instead of passing a list to
set()Prefer static methods over instance methods when possible
Prefer
withto open filesRefactor expensive
if-elifstatementRemove unused module(s)
Remove unused variable
Use a set instead of a list() to find key
Use
extend()for list concatenation
Readability
Avoid assigning a
lambdaexpression to a variableAvoid inline comments
Avoid
Noneas a redundant second argument todict.get()Avoid "non-Pythonic" attribute names
Avoid "non-Pythonic" class names
Avoid unnecessary name repetition in equality comparisions
Avoid unnecessary parentheses after keyword
Avoid unnecessary
passstatementsClean up unused imports
Consider using 'dt' as alias for datetime imports
not ... isused instead ofis notOmit
len()as upper boundaryOmit
len()for indexing/slicingPrefer
.format()over string concatenations via+Simplify repetetive unequal checks
Test object identity with
isoris notUse common abbreviations for libraries
Use dict comprehension
Use
isinstance()instead of comparing typesUse
isoris notto compare withNoneUse
.items()to iterate over a dictionaryUse named tuples when returning more than one value from a function
Use new raise syntax
Use unpacking to update multiple values at once
Use
zip()to iterate over a pair of lists
Security
Avoid using
eval()Avoid using
exec()Check published
CONSUMER_SECRETCheck published OAuth secret
Check published
OAuthtokenCheck published Stripe API key
Check usage of exploitable MD5 hashes
Upgrade from
md5tohashlib
Frameworks
Django
Access model manager through model class not instance
Always define
__str__or__unicode__for each modelAvoid directly altering custom many-to-many relationships
Avoid importing from
django.db.models.fieldsAvoid
null=Trueon string fieldsAvoid overwriting init method of model classes
Avoid two consecutive underscores in field name
Avoid using len() with RawQuerySet
Avoid using
locals()to populate view contextAvoid using RawQuerySet as boolean value
Call
super()when overwriting unittest methodsCheck identical value for
SERVER_EMAILandDEFAULT_FROM_EMAILDefine
get_absolute_urlwhenever possibleDirectly accessing
INSTALLED_APPSDo not interact with database within ready()
Do not override field attributes in child model
Don't pass args and kwargs to
reverse()Don't use joins with
update()Don't use same path for
MEDIA_ROOTandSTATIC_ROOTDon't use same path for
MEDIA_URLandSTATIC_URLDon't use string formatting on raw queries
Don't use unsupported arguments on
FileFieldDouble-check published secret key
Duplicate application names
Ensure indexes on your Django models
Inherit proxy models from non-proxy parent
Invalid import from
django.conf.settingsLeverage queryset cache as much as possible
Missing required field in settings
Model attribute overwrites method definition
Place database manipulations in try-except blocks
Remove redundant import of global_settings
SECURE_PROXY_SSL_HEADERsetSet
ALLOWED_HOSTSwhenDEBUG=FalseTry to start test methods with "test_"
Use a
NullBooleanFieldUse
django.conf.urls.url()instances for urlpatternsUse django.test.TestCase when accessing the database
Use forward slashes in settings
Use getobjector_404() instead of catching ObjectDoesNotExist
Use model class as first argument for field type
Use reverse() instead of hard-coded URL
Use
settings()method instead of manipulating settings directlyUsing
BinaryFieldto store raw binary data
Flask
Avoid two consecutive underscores in column name
Consider using
url_prefixfor views with similar routesDefine
SERVER_NAMEwhen using sub domainsDefine
url_prefixorsubdomainduring blueprint registrationPrevent SQL injections by avoiding string interpolations
routeshould be the outermost decoratorUse converter for type checking url variables
Use relative imports
Plone
Catching ImportError to detect package availability
Comma-separated imports
Prefer explicitly numbering replacement fields in a format string
Refactor deprecated unittest aliases
Using
request.AUTHENTICATED_USER
Odoo
Avoid calling magic methods
Avoid
Noneas a redundant second argument todict.get()Avoid temporary
kwargsAvoid using intermediate variables whenever possible
Avoid using Java style dicts
Avoid using
len(x)to check if x is emptyAvoid using
.update()to create merged dictionariesdict.has_key()deprecatedOdoo model defaults require four parameters
Use constants and avoid magic numbers
Use
isinstance()to check for typeUse tuple as 2nd argument of
isinstance()to avoid repetitionUse
.update()instead of setting keys individually