Some years ago I embarked into the adventure of learning Python, I already knew some other programming languages like PHP (the first language which introduced me to web development), JavaScript (to which I was already pretty good at it, and was writing a UI library) and C# which was responsible for my income at the time.
I learned Python by working on an app solo, and thus I incorporated many JavaScript and C# way of doing things into my code, which was terrible, though sometimes it worked. It took me some time, reading other’s people code and working with others to actually become better at the language. Today I’d like to go through with you on some of the mistakes I did (code-wise) when learning Python.
Misunderstanding Python scopes
Python scope resolution is based on what is known as the LEGB rule, which is shorthand for Local, Enclosing, Global, Built-in. Even though it looks pretty simple, it’s was very confusing for me at the time. So, let’s have a look at the example below:
For the code above I’d have expected it to work, and altering the global variable x
to finally printing 6
. But, it can get weirder, let’s look at the following altered code:
What in the world is going on? In one code snippet, the global variableX
gives anUnboundLocalError
. However, when we try to print the variable, it works. The has to do with scoping. When you make an assignment to a variable in a scope (e.g. the function scope), that variable becomes local to that scope and shadows any similarly named variable in the outer scope. This is what happened in the first scenario when we didx += 1
.
If what we are intending is to access the global variablex
as in the case of our functionfoo()
, we could do something like this:
By using the keywordglobal
, it allows the inner scope to access the variable declared in the global scope, meaning variables that are not defined in any function. Similarly, we could usenonlocal
to produce a similar effect:
nonlocal
asglobal
allows us to access variables from an outer scope, however, in the case ofnonlocal
, you can bound an object on a parent scope or the global scope.
Modifying a list while iterating over it
Though this error is not only common to Python, it’s an error commonly spotted among new Python developers, and even to some experienced developers. Though sometimes it may not seem so obvious, under certain occasions we end up modifying the array we’re currently iterating resulting in unappropriated behavior. Or if we are lucky, we get an error and easily notice it.
But let me give you an example of what I mean. Let’ say that given an array you need to reduce that array to contain only the even elements, you may attempt to do something like:
In the scenario described, when deleting an element for a list or array while iterating, we get an error as we try to access an item that is not there anymore. This is bad practice and should be avoided, there are better ways to achieve similar things in Python, among them are list comprehensions:
You could also use thefilter
function to achieve the same thing. Though it works, some argue this is not the Pythonic way of doing it, and I kind of agree. But I don’t want to get into the middle of that discussion, I’d rather give you the options, and you can research and decide:
Variable binding in closures
I’d like to start with a quiz I posted on twitter (@livecodestream) where I asked people about what they think the result of the following snippet would be:
For many people, myself included, the first time we encounter this problem we think that the result is:
However, the code actually resulted in something totally different and I was very puzzled at this. What is actually happening is that Python would do a late-binding behavior, according to which the values of variables used in closures are looked up at the time the inner function is called. So in our example, whenever any of the returned functions are called, the value of i
is looked up in the surrounding scope at the time it is called.
A solution to this problem may seem a bit ‘hacky,’ but it actually works:
By using the default argument of the lambda function to pass the value of i
, we can generate the functions to do the desired behavior. I was very puzzled by this solution, and I still consider it not very elegant, however, some people love it.
Name clashing with Python Standard Library modules
This issue was actually pretty common when first started working with Python. Even today, I sometimes make this mistake. The issue comes as a result of naming one of your modules with the same name as a module in the standard library that ships with Python. For example, you might have a module named email.py in your code, which would be in conflict with the standard library module of the same name.
Perhaps the name clashing by itself won’t generate any issues with your code, but sometimes we override a function or module of the Python standard library, which is later used in an installed library, and it conflicts either by throwing errors or misbehaving. In any case, it’s a bad situation to have.
A classic mistake is the following:
By simply creating a variable named list
we broke the access to the list
function. Even though there are other ways of accessing it (e.g. __builtins__.list()
), we should avoid this kind of name.
This article does not cover all the common mistakes developers do when coding in Python, but rather those things I struggled the most. If you want to know more about how to write great Python code and avoiding some other mistakes I recommend you to read Make Your Code Great, Python Style.
This article was originally published on Live Code Stream by Juan Cruz Martinez, founder and publisher of Live Code Stream. He is a Software Engineer with more than 10 years of experience in the field, working in a wide variety of projects, from open source solutions to enterprise applications. Happily married, with a kid, officially engaged to JavaScript, in a love relationship with Python, and pursuing the writer’s dream! You can read this original piece here.
Live Code Stream is also available as a free weekly newsletter. Sign up for updates on everything related to programming, AI, and computer science in general.
Get the TNW newsletter
Get the most important tech news in your inbox each week.