General Coding Guidelines
These are the general guidelines to be followed:
It is recommended to upgrade the package dependency whenever possible although version pinning is a must.
See tools that can be used in development environment setup to ease your coding process.
Always use
python3. Latest stable is always recommended. Ensure version is no older than 2 versions back. i.e. if current stable is3.11then use atleast3.9.Indentation should always be space and width should always be 4.
File size and functionality:
- break files into modules if you feel they have multiple functionalities.
- Always try to adhere to single functionality or single class per file.
- Set a goal of approximate line numbers per file confining to relatable functionality.
Always go for pythonic syntax
- comprehensions over
mapand loop - minimal use of
lambda, useoperatormodule with keyfunctions insorted,groupbyetc. - ternary with
if elsein same line. Usingand orclause. i.e.value and req_value or defaultis not recommended.
- comprehensions over
Imports:
- Always
importspecific namespace. - Try to use parent namespace for actions. i.e.
import sys: sys.pathorimport sys.pathrather thatfrom sys import path - Never use
import *i.e.from MODULE import * - use namespace whenever possible. Use alias i.e.
as SOMEOTHERNAMESPACEfor collision of namespace
- Always
If you are using
elsewith loops that hasbreak. Just comment#nobreakfor reference as it is for that usage. See this for some clarity.for each in each_collection:
if condition:
break
else: #nobreak
WHEN break DOESNOT HAPPEN
while True:
if condition:
break
else: #nobreak
WHEN break DOESNOT HAPPENUse
pathlibfor path related use case rather thanos.pathUse type annotation or type hints for type safe code especially for newer projects. Look into tools for inference checker.
Dockercan be used for deployment. Usepythonimages fordocker.Use
generatorsandyieldinstead of data structures for high streams of data.Use
itertools,functoolsfor utilities andcollectionsfor data structures when needed.Use
is notandisforNone,TrueandFalsespecific check only. If most cases truthy and falsy can be checked withif VARNAME:.Strings:
- Adhere to one quote practice. Double quote is recommended. Python doesnot differentiate between ' or ". This may be controlled by
formatterused as well. - Should be interpolated with either fstring or
.formatmethods. Try to avoid%.format_mapshould be used for key mapped formatting.- use
fstringfor newer codebase as it is not compatible below version3.6.
+can be used for direct string concatenation. Usejoinmethod for concatenation instead of+=when iterating.
- Adhere to one quote practice. Double quote is recommended. Python doesnot differentiate between ' or ". This may be controlled by
Use
contextwhenever supported especially for io related closing actions.- i.e.
withstatement when supported. - Always remember to close on exit. i.e. if you open the file
closeonfinallyor better usewithorcontextlib.closing.
- i.e.
OOP
- While
pythonis an OOP, you can always choosefunctionsandmodulesoverclassif there is only oneobjectto be created likeSingletons. - Use
abcif you need abstraction. Mixins are more famous in python due to multiple inheritance.- Use
collectionsandcollections.abcfor data structures designs.
- Use
- Use
propertysetter getter only when you need readonly attributes.__variables can be used for some privacy. - Use
superfor overrides and parent calls. - Use inbuilt
dataclassesif available. Go forattrslibrary ifdataclassesis not present or you require a much richer library. - Use
classmethoddecorator for multiple initialization of classes as well asstaticmethodwhere needed.
- While
Use
pdbas debugger whenever required. Newer code can usebreakpointdirectly.Multi-threading can be especially used when we have io bound and network bound multiple operation. Multiprocessing can be used to use multiple cores.
- Recommended module is
concurrent.futuresin most cases. If lower level API is needed there is alwaysthreadingandmultiprocessingmodule. - Be very carefult on threads and locks, so always discuss what you are doing as it may not always be optimized.
- Use
asynciofor IO bound async flow. This is something new and constantly changing inpython. There are alternative liketrioas well.
- Recommended module is
Try to use configurations outside python files. Usually they are not git tracked so should be editable by others. Try
settings.pyorconfig.pyif you must. This cannot be the case for frameworks as they recommend their own practice mostly.Docstrings in code is a must. Please follow consistent format. google style is more readable and should be used except for
numpyrelated projects i.e. AI/ML projects where they follownumpystyle mostly.- If you must use
rststyle, be consistent with the team. - Try to be compatible with documenting tool such as
sphinx.
- If you must use
Recommended third party modules:
- For Relational Database:
- Use
sqlalchemycore for DB abstraction. This is particularly helpful when doing testing insqliteand some other database for production. Also, for query and parameters consistency. - Use
sqlalchemyORM or framework supported ORM when using specific framework. - Use DBAPI drivers such as
pyodbc,sqlite,mysqlclientetc only when you donot wantsqlalchemydependency or when you are very performance conscious. While the API will be mostly compatible for this as python has DBAPI specification. Parameters binding and some methods may be incompatible or unavailable. sqlalchemy core is recommended.
- Use
requestsfor http request stuff.aiohttporhttpxare also good.
attrsfor data oriented objects and classes design. If you don't want to usedataclasses.pytestfor tests.
- For Relational Database: