1.1 Split imports into 3 categories (stdlib, 3rdparty, internal imports), relative imports should be the last. Try to keep them sorted.
importdatetimeimportloggingfromdjango.utilsimporttimezonefromdjango.utils.translationimportugettext_lazyas_fromdjango.confimportsettingsfromdjango_states.machineimportStateMachine, StateDefinition, StateGroup, StateTransitionfromdjango_states.exceptionsimportTransitionValidationErrorfromourapp.notifications.handlersimportNOTIFICATION_METHODfromourapp.notificationsimportnotifiersfromourapp.module_a.providerimportTrustedfromourapp.activation.modelsimportXOrderfromourapp.porting.utilsimportget_closest_wish_datefrom .modelsimportInportfrom .utilsimportadd_inport_s3
1.2 Use imports for packages and modules only, if it is possible.
importdatetime# never: from datetime import datetime or similarimportlogging# never: from logging import getLoggerimportmock# never from mock import Mockimportrandomimportuuidimportbson# never from bson import ObjectIdfromdjango.utilsimporttimezone# never: from django.utils.timezone import now
1.3 If import exceeded line length limit, format it like that:
fromourapp.porting.tasksimport ( task_a, task_b, task_c, # <- comma here )
2.1function calls
abc=qwe(dsadsa(product.to_dict(), cls=DecimalEncoder, mimetype='application/json')) # badabc=qwe(dsadsa(product.to_dict(), cls=DecimalEncoder, mimetype='application/json')) # badabc=qwe(dsadsa(product.to_dict(), cls=DecimalEncoder, mimetype='application/json')) # badabc=qwe(dsadsa( product.to_dict(), cls=DecimalEncoder, mimetype='application/json', # <- comma here )) # OKabc=qwe( dsadsa( product.to_dict(), cls=DecimalEncoder, mimetype='application/json', # <- comma here ) ) # could be too# especially when qwe has one aditional keyword parameter:abc=qwe( dsadsa( product.to_dict(), cls=DecimalEncoder, mimetype='application/json', # <- comma here ), # <- comma heredupa=2, # <- comma here ) # OK
2.2dict class
# badabc=dict(abc=2, cde=5, mama='tata', tata='mama', raz=1, dwa=2) # badabc=dict(abc=2, cde=5, mama='tata', tata='mama', raz=1, dwa=2) # bad abc=dict( abc=2, cde=5, mama='tata', tata='mama', raz=1, dwa=2 ) # badabc=dict( abc=2, cde=5, mama='tata', tata='mama', raz=1, dwa=2, ) # goodabc=dict( abc=2, cde=5, mama='tata', tata='mama', raz=1, dwa=2, # <- comma here ! )
2.3dict curly brackets
# badabc= {'abc': 2, 'cde': 5, 'mama': 'tata', 'tata': 'mama', 'raz': 1, 'dwa': 2} # badabc= {'abc': 2, 'cde': 5, 'mama': 'tata', 'tata': 'mama', 'raz': 1, 'dwa': 2} # bad abc= { 'abc': 2, 'cde': 5, 'mama': 'tata', 'tata': 'mama', 'raz': 1, 'dwa': 2 } # badabc= { 'abc': 2, 'cde': 5, 'mama': 'tata', 'tata': 'mama', 'raz': 1, 'dwa': 2, } # goodabc= { 'abc': 2, 'cde': 5, 'mama': 'tata', 'tata': 'mama', 'raz': 1, 'dwa': 2, # <- comma here ! }
2.4func call and dicts
abc=abc({ 'a': 1, 'b': 3, 'c': 4, # <- comma here ! }) abc=abc(dict( a=1, b=2, c=3, # <- comma here ! )) nokaut_api_params=urllib.urlencode({ 'key': str(nokaut_key), 'keyword': str(keyword), 'format': 'xml', 'method': 'nokaut.Product.getByKeyword', 'sort_direction': 'price_asc', 'returnType': 'full', 'limit': '1', # <- comma here ! })
2.5list comprehension
# baddata= [model_fieldforform_field, model_fieldinfieldsifform_fieldinform] # baddata= [model_fieldforform_field, model_fieldinfieldsifform_fieldinform ] # gooddata= [ model_fieldforform_field, model_fieldinfieldsifform_fieldinform ] # good (if exceeding line length limit)data= [ model_fieldforform_field, model_fieldinfieldsifform_fieldinform ]
2.6dict comprehension
# baddata= {model_field: form[form_field].dataforform_field, model_fieldinfieldsifform_fieldinform} # gooddata= { model_field: form[form_field].dataforform_field, model_fieldinfieldsifform_fieldinform } # good (if exceeding line length limit)data= { model_field: form[form_field].dataforform_field, model_fieldinfieldsifform_fieldinform }
2.7if statement if conditions are too long, store their result in variable with meaningful name
# badifabcisNoneandbisTrueandc=='mama' \ andx!=1orcin ('mama', 'tata') \ orbabcia.age>100: # checks if thing should be done# do something big# badif (abcisNoneandbisTrueandc=='mama'andx!=1orcin ('mama', 'tata') orbabcia.age>100): # checks if thing should be done# do something big# goodshould_be_done= ( # no comment needed !abcisNoneandbisTrueandc=='mama'andx!=1orcin ('mama', 'tata') orbabcia.age>100 ) ifshould_be_done: # do something big
2.8slashes never use them
# bad:defx(): a_identity=self.aidentityconfirm_set.filter(uuid=self.id_at_provider).first() returna_identity.get_person_who_registed_y().get_full_name()\ ifa_identityanda_identity.state=="confirmed"else"A identity is not confirmed yet"# good:defx(): a_identity=self.aidentityconfirm_set.filter(uuid=self.id_at_provider).first() ifa_identityanda_identity.state=="confirmed": returna_identity.get_person_who_registed_y().get_full_name() else: return"A identity is not confirmed yet"# there is one exception when you can use slashes, when using chaining methods, examples:# django ORM:posts=Post.objects.filter(blog__id=x)\ .filter(created_at__gt=y)\ .filter(desc__contains=z)\ .order_by('created_at') # Google App Engine NDBgreetings=Greeting.query_book(ancestor_key)\ .filter(Greeting.userid>=40)\ .filter(Greeting.userid<100)\ .fetch(self.GREETINGS_PER_PAGE) # SQLAlchemyfiles=File.query.filter(File.used.is_(False))\ .filter(File.modified<daysago2)\ .yield_per(10) # mongoalchemyplace=session.query(Places).filter_by(loc=a)\ .filter(created_at=b)\ .descending('created_at').first()
2.9Single quotes vs double quotes Use double quotes around strings that are natural language messages and single quotes for small symbol-like strings, for example:
LIGHT_MESSAGES= { 'english': "There are 3 lights.", 'pirate': "Arr! Thar be 3 lights." } deflights_message(language, number_of_lights): """Return a language-appropriate string reporting the light count."""returnLIGHT_MESSAGES[language] defis_pirate(message): """Return True if the given message sounds piratical."""returnre.search(r"(?i)(arr|avast|yohoho)!", message) isnotNone
- 3.1Bail early is idiomatic coding style.
# BAD, really baddefbad_method(a):
b=one(a)
ifb.isgood():
c=two(b)
ifc.isok():
d=three(c)
ifd.hasX():
returndelse:
raiseNoXErrorelse:
raiseNotOKError# GOOD, more clear, more obvious defgood_method(a):
b=one(a)
ifnotb.isgood():
returnc=two(b)
ifnotc.isok()
raiseNotOKErrord=three(c)
ifnotd.hasX():
raiseNoXErrorreturnd