[Python] Coding Practices
By: Alireza Goudarzi
Tags: Software Engineering, Software Development, Python

I am seeing some tensions in onboarding new team members and a lot of it is about coding practices and common mindset that is not shared with people who come from other disciplines. I will add to this list as I come across cases and I hope this serves other people joining Datance and the broader community. Disclaimer: I’m an ex-software engineer who hasn’t done industrial software engineering for more than 10 years. In many of these matters I have referred to partner who’s been spending the last 10 years producing software across a wide range of languages and environments.

Lambdas

Anonymous functions are powerful concepts, but they have to be used with caution. Lambdas semantics and syntax differs between languages and depending on the language and situation it imposes harsh restrictions and may also have other side effects. So after calming down from excitement when you learn about lambdas the first time, you should thinking clearly about what it is you want to achieve in your code and how you want to use lambdas. In Javascript for instance we also have to deal with the extra inconsistency between arrow function style of defining lambda and the standard function keyword. Remember when you define arrow function for example you don’t have access to this . Fortunately in this case docstring is not affected.

In Python however, we have one-liner function definition with the help of lambda. But this comes at the cost of loosing readability of docstring and your function syntax. As of now I am not aware of other semantics that maybe affected here. Also with normal setup you wouldn’t be able to type hint your lambdas and you won’t get any help from your IDE (say VSCode) to remind of the parameters and even if it did, it would defeat the purpose of an anonymous function. Now of course for type hinting alone you cold resort to something like this:

from typing import Callable StrLen: Callable[[str, int] = lambda Var1: len(Var1)

But even this will not give you the convenience of using your automatic docString generator, or even your IDE’s help with the parameters. So at least at the time of this writing I don’t know what the point would be. As of now the only reasonable use of lambdas I can think of is crafting partial functions (which is a whole topic of its own if you are not used to functional programming from pure functional languages, but maybe that is for another time. If you have comments or edits on anything here, I’m always looking to learn more.

2. Imports

When you are working with layered architectures it is always good to be aware of your hierarchy. Therefore try to avoid doing things like from Package.Module import Function . Ideally we don’t want to see Function() in our code. Not to mention if you are importing several modules you will get into namespace conflicts if modules have functions of the same name. Keep your from...import... knowledge for writing importers, which means most probably the maintainer of frameworks need to deal with it.

3. Information Flow

Always try to stick to one-directional information flow. This will avoid bugs, and ease troubleshooting and architecting your frameworks. What do I mean by that. Imagine something like this:

src/data/model/Models.py

src/helpers/Loaders.py

src/main.py

Here Main.py is responsible for managing the information flow. A Datasource object is created in Models.py . We would import Models and Loaders in Main, then call Loaders.Load(Datasource) from Main. Be sure not to call Load() inside the Loaders.py .

4. Dynamic Variable Generation

If you are hot on dynamism, you will probably fall victim to this. But for heaven’s sake no eval() or globals() for dynamic variable generation in your local or global scope. You are undermining you IDE to help you and your colleagues or your future self when trying to modify or trouble shoot your code.

5. No or Limited Side Effects

Side effects are when a function creates a change in its context. All communication with a function should be through the parameters and the return value. Functions that change their environment are not pure functions and make your entire software error prone. They may sometimes be unavoidable, but their use MUST extremely limited.