Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python initializes method parameters instead of using default values

I have created a class:

class PolicyJSON:
    def __init__(this, path:str="", values:dict={}, children:list=[], parent=None):
        this.path = path
        this.values = values
        this.children = children
        this.parent = parent 
        this.path = this.getfullpath()

This class is hierarchical – it can have many children of it’s type, and it can have a parent (of it’s type). I have wrote several hundreds of lines of code already, basically creating whole hierarchy, my codes are working just okay so I was happy, until now.
I have started spawning multiple instances of these hierarchies (see mymethod below), only to find out that for some reason python simply ignores parameter default values defined in __init__(), and, for some weird reason, it’s putting existing variables in these places!

Can someone please explain to me, what is going on here, and how to make class behave like a class?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Basically, I have lots of code that generates PolicyJSON instances with hierarchical data, and then, I do this:

# here is lots of code that also creates PolicyJSON 
# instances, then I have something like below:

def mymethod(someparams):
    result = PolicyJSON()
    return result
myinstance = mymethod(...)

At this point, result, instead of being empty, already has data filled in – I can do result.children and it will return actual data! When I paused debugger at that result = PolicyJSON() line, and then Jumped in (F11), the __init__() constructor had its parameters filled in with data (i.e. children:list=[] was not [], but an actual array with data. How? Why? How can I make it behave "the normal" way?

>Solution :

Let’s consider a minimal example:

...   def __init__(self, a=[]):
...     self.a = a
... 
>>> a = A()
>>> a.a
[]
>>> a.a.append(4)
>>> a.a
[4]
>>> b = A()
>>> b
<__main__.A object at 0x105bb8260>
>>> b.a
[4]
>>> 

Your defaults are evaluated at the time the method is created, not each time it’s called. This affects any mutable object you provide as a default. Values like integers, floating point numbers, and strings are not affected.

Rather you can specify a default is None and then set it appropriately within the __init__ method.

>>> class B(object):
...   def __init__(self, b=None):
...     self.b = (b if b is not None else [])
... 
>>> b = B()
>>> b.b.append(9)
>>> b.b
[9]
>>> c = B()
>>> c.b
[]
>>>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading