scope of optional arguments
-
On 14/02/2013 at 09:29, xxxxxxxx wrote:
Hi,
I have got a stupid question I guess. It is actually not really c4d related, but I am asking here
anyway. I have got a quite simple node token class. It basically just stores instances of its own
type.class rhTreeToken(object) : def __init__(self, tokentype, children = None, subtype = None, value = None) : if children == None: self.Children = [] else: self.Children = children self.Subtype = subtype self.Type = tokentype self.Value = value ...
When I write the same fragment this way,
class rhTreeToken(object) : def __init__(self, tokentype, children = [], subtype = None, value = None) : or def __init__(self, tokentype, children = list(), subtype = None, value = None) : ...
my whole node structure virtually explodes. I get an infinite recursion, data from other nodes
appear as children of nodes they were never assigned to, the whole class seems to share the
memory for rhTreeToken.Children then.I suspect the optional arguments are not actually attached to the specific class instance, but
stored somewhere in Pyhton, so that the empty list would be shared by all instances. But i could
not find any proof / explanation for that, is that correct ?thanks for reading,
a pretty confused,
ferdinand -
On 14/02/2013 at 09:44, xxxxxxxx wrote:
Hi Ferdinand,
the behavior is correct and is not actually related to the scope. The default-value for an argument
is not created every-time the function is called, it is stored by reference.def magic(v, l=[]) : l.append(v) print "l:", l magic(0) magic(1) magic(2) magic(3)
You can also look-up the default-values for a function:
print magic.func_defaults
Or even change:
magic(0) magic(1) magic.func_defaults = ([],) magic(2) magic(3)
You either have to keep with the None default-value, or copy the list for assignment.
self.children = children[:]
-Niklas
-
On 14/02/2013 at 09:57, xxxxxxxx wrote:
hey thanks for the quick, answer.
i did not knew that you could do this [:] . Just to be sure that i fully understand this -
[:] is the list from start to end ? -
On 14/02/2013 at 09:57, xxxxxxxx wrote:
Hi Ferdinand,
exactly, the list from start to end => copy of the list.
You can also use the copy module if you find it more obvious. This also has the
advantage, that it will be supported by more sequence-types than tuples or
lists.import copy list_1 = ["foo", "bar"] list_2 = copy.copy(l_1) print list_1 == list_2 # True print list_1 is list_2 # False
-Niklas
-
On 14/02/2013 at 10:14, xxxxxxxx wrote:
no, i like it, it is short, it is crpytic, chances are good, that i cannot my own code
in two weeks from now. it is perfect