Python: some of the best practices you must know
As you may know, Python is one of the most famous programming languages at the moment. Developers all over the world are using it for back-end web development, data analysis, artificial intelligence, and scientific computing.
This useful language is easy to learn, has a large community and developers who have experience working with Python find better career opportunities than others.
Those advantages stated why software engineers everywhere should choose to learn Python.
This article by Designveloper will show you some of the best practices when using Python in your project. Enjoy.
I. Style
1. Naming:
There are a lot of different naming styles. It helps to be able to recognize what naming style is being used, independently from what they are used for.
Variables, functions, methods, packages, modules:Lower_case_with_underscores
Classes and Exceptions:CapWords
Protected methods and internal functions:_single_leading_underscore(self, ...)
Private methods:__double_leading_underscore(self, ...)
Constants:ALL_CAPS_WITH_UNDERSCORES
2. General Naming Guidelines: Names to Avoid
Don’t use one-letter variables especially the characters ‘l’ (lowercase letter el), ‘O’ (uppercase letter oh), or ‘I’ (uppercase letter eye).
Exception: In very short blocks, when the meaning is clearly visible from the immediate context.
Finefor e in elements:
e.mutate()
3. Avoid redundant labeling.
Yesimport audio
core = audio.Core()
controller = audio.Controller()
Noelements = ...
active_elements = ...
defunct_elements ...
4. Avoid getter and setter methods.
Yesperson.age = 42
Noperson.set_age(42)
II. Imports
Import entire modules instead of individual symbols within a module.
For example, for a top-level module canteen
that has a file canteen/sessions.py,
Yesimport canteen
import canteen.sessions
from canteen import sessions
Nofrom canteen import get_user # Symbol from canteen/__init__.py
from canteen.sessions import get_session # Symbol from canteen/sessions.py
Exception: For third-party code where documentation explicitly says to import individual symbols.
Imports should be grouped in the following order:
- Standard library imports.
- Related third-party imports.
- Local application/library specific imports.
You should put a blank line between each group of imports.
III. Documentation
Use one-line docstrings for obvious functions."""Return the pathname of ``foo``."""
Multiline docstrings should include
- Summary line
- Use case, if appropriate
- Args
- Return type and semantics, unless
none
is returned.
"""Train a model to classify Foos and Bars.
Usage::
>>> import klassify
>>> data = [("green", "foo"), ("orange", "bar")]
>>> classifier = klassify.train(data)
:param train_data: A list of tuples of the form ``(color, label)``.
:rtype: A :class:`Classifier `
"""
Notes
- Use action words (“Return”) rather than descriptions (“Returns”).
- Document __init__ methods in the docstring for the class.
class Person(object):
"""A simple representation of a human being.
:param name: A string, the person's name.
:param age: An int, the person's age.
""" def __init__(self, name, age):
self.name = name
self.age = age
IV. On comments
Use them sparingly. Prefer code readability to writing a lot of comments. Often, small methods are more effective than comments.
No# If the sign is a stop sign
if sign.color == 'red' and sign.sides == 8:
stop()
Yesdef is_stop_sign(sign):
return sign.color == 'red' and sign.sides == 8
if is_stop_sign(sign):
stop()
When you do write comments, remember: “Strunk and White apply.”
V. Line Lengths
Don’t stress over it. 80–100 characters are fine.
Use parentheses for line continuations.wiki = (
"The Colt Python is a .357 Magnum caliber revolver formerly manufactured "
"by Colt's Manufacturing Company of Hartford, Connecticut. It is sometimes "
'referred to as a "Combat Magnum". It was first introduced in 1955, the '
"same year as Smith & Wesson's M29 .44 Magnum."
)
VI. Testing
Strive for 100% code coverage, but don’t get obsessed over the coverage score.
1. General testing guidelines
- Use long, descriptive names. This often obviates the need for docstrings in test methods.
- Tests should be isolated. Don’t interact with a real database or network. Use a separate test database that gets torn down or uses mock objects.
- Prefer factories to fixtures.
- Never let incomplete tests pass, else you run the risk of forgetting about them. Instead, add a placeholder like
assert False, "TODO: finish me"
2. Unit Tests
- Focus on one tiny bit of functionality.
- Should be fast, but a slow test is better than no test.
- It often makes sense to have one test case class for a single class or model.
import unittest
import factories
class PersonTest(unittest.TestCase):
def setUp(self):
self.person = factories.PersonFactory()
def test_has_age_in_dog_years(self):
self.assertEqual(self.person.dog_years, self.person.age / 7)
3. Functional Tests
Functional tests are higher level tests that are closer to how an end-user would interact with your application. They are typically used for web and GUI applications.
- Write tests as a scenario. Testcase and test method names should read like a scenario description.
- Use comments to write out stories, before writing the test code.
import unittest
class TestAUser(unittest.TestCase):
def test_can_write_a_blog_post(self):]
# Goes to the her dashboard
...
# Clicks "New Post"
...
# Fills out the post form
...
# Clicks "Submit"
...
# Can see the new post
...
Notice how the test case and test method read together like “Test A User can write a blog post”.
Source: The Best of the Best Practices (BOBP) Guide for Python via gist.github.com