Weird Python behaviour
Benjamin Kaplan
benjamin.kaplan at case.edu
Tue Aug 10 10:43:22 EDT 2010
On Tue, Aug 10, 2010 at 4:58 AM, Jonas Nilsson <jmnc at spray.se> wrote:
> Hello,
>
> Lets say that I want to feed an optional list to class constructor:
>
> class Family():
> def __init__(self, fName, members = []):
> self.fName = fName
> self.members = members
>
> Now, lets add members to two different instances of Family:
>
> f1 = Family("Smith")
> f1.members.append("Bill")
>
> f2 = Family("Smithers")
> f2.members.append("Joe")
>
> Finally, lets look at the members in the Smithers family:
>
> print f2.members
> output: ['Bill', 'Joe']
>
> Why on earth is the output ['Bill', 'Joe']!? Is there a simple solution that
> separates f1 and f2 without forcing me to write code for the special case
> when you don't feed members to the __init__()-function?
>
> /Jonas
In python, a function definition is an executable statement, not a
declaration. Default args only get evaluated once- when the function
is first created. You have to use a sentinel value and create the
object inside the function if you want it to get executed every time.
class Family():
def __init__(self, fName, members = None):
if members is None :
members = []
self.fName = fName
self.members = members
If None is a valid argument to this function, then make a dummy object
and check identity (to make sure it's *that* object and not just
something that evaluates equal).
sentinel = object()
def something_that_accepts_none(foo = sentinel) :
if foo is sentinel :
foo = {}
# other stuff
More information about the Python-list
mailing list