Brandon Konkle
Brandon Konkle

Software Architect at Community Funded, GraphQL/Node/React developer, TypeScript nerd, Linux enthusiast, supporter of social justice, loving husband & dad.

I'm a Node & React developer with more than a decade of experience creating high performance web applications and architectures. If you're looking for help with your next project, hire me today!

Share


Tags


avrt

Bitten by Python's Pass-By-Reference

I just got bitten by an interesting bug related to Python's pass-by-reference feature. I had a class method (mymethod) with a keyword argument (mykwarg) that d…

Brandon KonkleBrandon Konkle

I just got bitten by an interesting bug related to Python's pass-by-reference feature. I had a class method (mymethod) with a keyword argument (mykwarg) that defaulted to {}. I thought that each time mymethod was called, if mykwarg wasn't passed then it would default to an empty dict.

In reality, when the class was read by Python it evaluated the {} and made the default value a reference to the dict in memory. So each time mymethod was called without passing mykwarg, it was defaulting to that memory reference which contained data from a previous use. Here's an example class:

:::python
class MyClass(object):
    def my_method(self, my_kwarg={}):
        return my_kwarg    

And here's an iPython shell session illustrating what I mean:

In [2]: first_class = MyClass()

In [3]: kwarg = first_class.my_method()

In [4]: kwarg
Out[4]: {}

In [5]: kwarg.update({'foo': 'bar'})

In [6]: kwarg
Out[6]: {'foo': 'bar'}

In [7]: kwarg = first_class.my_method()

In [8]: kwarg
Out[8]: {'foo': 'bar'}

In [9]: second_class = MyClass()

In [10]: other_kwarg = second_class.my_method()

In [11]: other_kwarg
Out[11]: {'foo': 'bar'}

The fact that the kwarg wasn't defaulting to a fresh dict each time led to a lot of confusion before I realized what was happening! There are a couple of ways to solve the issue, but the easiest is probably this:

:::python
class MyClass(object):
    def my_method(self, my_kwarg=None):
        my_kwarg = my_kwarg or {}
        return my_kwarg

I'm a Node & React developer with more than a decade of experience creating high performance web applications and architectures. If you're looking for help with your next project, hire me today!

View Comments