Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ulamlabs/python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

10 Commits

Repository files navigation

Python Style Guide

Table of Contents

  1. Inports
  2. Indentation
  3. Techniques

Inports

  • 1.1 Split imports into 3 categories (stdlib, 3rdparty, internal imports), relative imports should be the last. Try to keep them sorted.

    import datetime
    import logging
    from django.utils import timezone
    from django.utils.translation import ugettext_lazy as _
    from django.conf import settings
    from django_states.machine import StateMachine, StateDefinition, StateGroup, StateTransition
    from django_states.exceptions import TransitionValidationError
    from ourapp.notifications.handlers import NOTIFICATION_METHOD
    from ourapp.notifications import notifiers
    from ourapp.module_a.provider import Trusted
    from ourapp.activation.models import XOrder
    from ourapp.porting.utils import get_closest_wish_date
    from .models import Inport
    from .utils import add_inport_s3

  • 1.2 Use imports for packages and modules only, if it is possible.

    import datetime # never: from datetime import datetime or similar
    import logging # never: from logging import getLogger
    import mock # never from mock import Mock
    import random
    import uuid
    import bson # never from bson import ObjectId
    from django.utils import timezone # never: from django.utils.timezone import now

  • 1.3 If import exceeded line length limit, format it like that:

    from ourapp.porting.tasks import (
     task_a,
     task_b,
     task_c, # <- comma here
    )

Indentation

  • 2.1 function calls

    abc = qwe(dsadsa(product.to_dict(), cls=DecimalEncoder, mimetype='application/json')) # bad
    abc = qwe(dsadsa(product.to_dict(), cls=DecimalEncoder,
     mimetype='application/json')) # bad
    abc = qwe(dsadsa(product.to_dict(),
     cls=DecimalEncoder,
     mimetype='application/json')) # bad
    abc = qwe(dsadsa(
     product.to_dict(),
     cls=DecimalEncoder,
     mimetype='application/json', # <- comma here
    )) # OK
    abc = 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 here
     dupa=2, # <- comma here
    ) # OK

  • 2.2 dict class

    # bad
    abc = 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)
    # bad 
    abc = 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,
    )
    # good
    abc = dict(
     abc=2,
     cde=5,
     mama='tata',
     tata='mama',
     raz=1,
     dwa=2, # <- comma here !
    ) 

  • 2.3 dict curly brackets

    # bad
    abc = {'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}
    # bad 
    abc = {
     '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,
    }
    # good
    abc = {
     'abc': 2,
     'cde': 5,
     'mama': 'tata',
     'tata': 'mama',
     'raz': 1,
     'dwa': 2, # <- comma here !
    }

  • 2.4 func 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.5 list comprehension

     # bad
     data = [model_field
     for form_field, model_field in fields if form_field in form]
     # bad
     data = [model_field
     for form_field, model_field in fields if form_field in form
     ]
     # good
     data = [
     model_field
     for form_field, model_field in fields if form_field in form
     ]
     # good (if exceeding line length limit)
     data = [
     model_field
     for form_field, model_field in fields
     if form_field in form
     ]

  • 2.6 dict comprehension

     # bad
     data = {model_field: form[form_field].data
     for form_field, model_field in fields if form_field in form}
     # good
     data = {
     model_field: form[form_field].data
     for form_field, model_field in fields if form_field in form
     }
     # good (if exceeding line length limit)
     data = {
     model_field: form[form_field].data
     for form_field, model_field in fields
     if form_field in form
     }

  • 2.7 if statement if conditions are too long, store their result in variable with meaningful name

    # bad
    if abc is None and b is True and c == 'mama' \
     and x != 1 or c in ('mama', 'tata') \
     or babcia.age > 100: # checks if thing should be done
     # do something big
    # bad
    if (abc is None and b is True and c == 'mama'
     and x != 1 or c in ('mama', 'tata')
     or babcia.age > 100): # checks if thing should be done
     # do something big
    # good
    should_be_done = ( # no comment needed !
     abc is None and
     b is True and
     c == 'mama'and
     x != 1 or
     c in ('mama', 'tata') or
     babcia.age > 100
    )
    if should_be_done:
     # do something big

  • 2.8 slashes never use them

    # bad:
    def x():
     a_identity = self.aidentityconfirm_set.filter(uuid=self.id_at_provider).first()
     return a_identity.get_person_who_registed_y().get_full_name()\
     if a_identity and a_identity.state == "confirmed" else "A identity is not confirmed yet"
    # good:
    def x():
     a_identity = self.aidentityconfirm_set.filter(uuid=self.id_at_provider).first()
     if a_identity and a_identity.state == "confirmed":
     return a_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 NDB
    greetings = Greeting.query_book(ancestor_key)\
     .filter(Greeting.userid >= 40)\
     .filter(Greeting.userid < 100)\
     .fetch(self.GREETINGS_PER_PAGE)
     
    # SQLAlchemy
    files = File.query.filter(File.used.is_(False))\
     .filter(File.modified < daysago2)\
     .yield_per(10)
    # mongoalchemy
    place = session.query(Places).filter_by(loc=a)\
     .filter(created_at=b)\
     .descending('created_at').first()

  • 2.9 Single 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."
    }
    def lights_message(language, number_of_lights):
     """Return a language-appropriate string reporting the light count."""
     return LIGHT_MESSAGES[language]
    def is_pirate(message):
     """Return True if the given message sounds piratical."""
     return re.search(r"(?i)(arr|avast|yohoho)!", message) is not None

    ref: http://stackoverflow.com/a/56190

Techniques

  • 3.1 Bail early is idiomatic coding style.
 # BAD, really bad
 def bad_method(a):
 b = one(a)
 if b.isgood():
 c = two(b)
 if c.isok():
 d = three(c)
 if d.hasX():
 return d
 else:
 raise NoXError
 else:
 raise NotOKError
 # GOOD, more clear, more obvious 
 def good_method(a):
 b = one(a)
 if not b.isgood():
 return
 c = two(b)
 if not c.isok()
 raise NotOKError
 d = three(c)
 if not d.hasX():
 raise NoXError
 return d

Releases

No releases published

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /