Mutable default arguments don't generally do what you want. Instead, try this:
class Node:
def __init__(self, wordList=None, adjacencyList=None):
if wordList is None:
self.wordList = []
else:
self.wordList = wordList
if adjacencyList is None:
self.adjacencyList = []
else:
self.adjacencyList = adjacencyList
Answer from Michael J. Barber on Stack OverflowMutable default arguments don't generally do what you want. Instead, try this:
class Node:
def __init__(self, wordList=None, adjacencyList=None):
if wordList is None:
self.wordList = []
else:
self.wordList = wordList
if adjacencyList is None:
self.adjacencyList = []
else:
self.adjacencyList = adjacencyList
Let's illustrate what's happening here:
Python 3.1.2 (r312:79147, Sep 27 2010, 09:45:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo:
... def __init__(self, x=[]):
... x.append(1)
...
>>> Foo.__init__.__defaults__
([],)
>>> f = Foo()
>>> Foo.__init__.__defaults__
([1],)
>>> f2 = Foo()
>>> Foo.__init__.__defaults__
([1, 1],)
You can see that the default arguments are stored in a tuple which is an attribute of the function in question. This actually has nothing to do with the class in question and goes for any function. In python 2, the attribute will be func.func_defaults.
As other posters have pointed out, you probably want to use None as a sentinel value and give each instance it's own list.
I am learning linked lists in python using classes.
One place that I am learning from is doing:
class Node:
def __init__(self, value):
self.value = value
self.next = NoneThe other place is doing:
class Node:
def __init__(self, value, next = None):
self.value = value
self.next = nextI can't figure out what difference it makes to use either init method. I tried to search this answer out using StackOverflow, but I had no luck.
I get that one is able to define 'next' during instantiation and the other would need to be defined after instantiation, but when would and why would you use one over the other?
edit: Thanks all. I am just starting to understand classes and still overthinking a little.
I'm wondering if this is the right way to do this. It seems... odd somehow to assign default values in the class definition, then default None in the constructor. I suppose I could give the same default values in both places, but again, this feels like unnecessarily repeating myself.
class MyClass:
name = 'Undefined'
number = -1
def __init__(self, name=None, number=None):
if name is not None:
self.name = name
if number is not None:
self.number = numberDon't use class attributes for that, that's not what they are there for. Use default arguments:
def __init__(self, name='Undefined', number=-1):
self.name = name
self.number = number
If any of the arguments are mutable, then you need to use the usual idiom:
def __init__(self, foo=None):
self.foo = [] if foo is None else foo
do you need these vars on the class level, given that they are supposed to be relevant on a per instance basis?
class MyClass:
def __init__(self, name='Undefined', number=-1):
self.name = name
self.number = number
def __str__(self):
return '{0.__class__.__name__}(name={0.name}, number={0.number})'.format(self)
print(MyClass())
print(MyClass(name='Joe'))
print(MyClass(number=11))
print(MyClass(name='Joe', number=11))
Extending bp's answer, I wanted to show you what he meant by immutable types.
First, this is okay:
>>> class TestB():
... def __init__(self, attr=1):
... self.attr = attr
...
>>> a = TestB()
>>> b = TestB()
>>> a.attr = 2
>>> a.attr
2
>>> b.attr
1
However, this only works for immutable (unchangable) types. If the default value was mutable (meaning it can be replaced), this would happen instead:
>>> class Test():
... def __init__(self, attr=[]):
... self.attr = attr
...
>>> a = Test()
>>> b = Test()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[1]
>>>
Note that both a and b have a shared attribute. This is often unwanted.
This is the Pythonic way of defining default values for instance variables, when the type is mutable:
>>> class TestC():
... def __init__(self, attr=None):
... if attr is None:
... attr = []
... self.attr = attr
...
>>> a = TestC()
>>> b = TestC()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[]
The reason my first snippet of code works is because, with immutable types, Python creates a new instance of it whenever you want one. If you needed to add 1 to 1, Python makes a new 2 for you, because the old 1 cannot be changed. The reason is mostly for hashing, I believe.
The two snippets do different things, so it's not a matter of taste but a matter of what's the right behaviour in your context. Python documentation explains the difference, but here are some examples:
Exhibit A
class Foo:
def __init__(self):
self.num = 1
This binds num to the Foo instances. Change to this field is not propagated to other instances.
Thus:
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1
Exhibit B
class Bar:
num = 1
This binds num to the Bar class. Changes are propagated!
>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2 #this creates an INSTANCE variable that HIDES the propagation
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3
Actual answer
If I do not require a class variable, but only need to set a default value for my instance variables, are both methods equally good? Or one of them more 'pythonic' than the other?
The code in exhibit B is plain wrong for this: why would you want to bind a class attribute (default value on instance creation) to the single instance?
The code in exhibit A is okay.
If you want to give defaults for instance variables in your constructor I would however do this:
class Foo:
def __init__(self, num = None):
self.num = num if num is not None else 1
...or even:
class Foo:
DEFAULT_NUM = 1
def __init__(self, num = None):
self.num = num if num is not None else DEFAULT_NUM
...or even: (preferrable, but if and only if you are dealing with immutable types!)
class Foo:
def __init__(self, num = 1):
self.num = num
This way you can do:
foo1 = Foo(4)
foo2 = Foo() #use default