[Tutor] When to use def __init__ when making a class?
Steven D'Aprano
steve at pearwood.info
Wed Aug 3 03:25:33 CEST 2011
brandon w wrote:
> I have two questions:
>
> 1) When should I use "def __init__(self):" when I create a class?
Whenever you need something to happen when you create an instance.
> 2) Would these two classes have the same effect?
Technically, no, but in practice, you would find it hard to see the
difference for the example given. But for slightly different examples,
the difference would be astonishing.
> class Name:
> def __init__(self):
> man = Marcus
> woman = Jasmine
> return self.man, self.woman
Did you try the code before posting it?
Three problems with it:
(1) Firstly, Marcus and Jasmine are not built-in Python commands, so
trying to execute man = Marcus raises NameError. You need to use
quotation marks to turn it into a string.
(2) Fixing that problem, man = "Marcus" doesn't do what you expect
either, because it creates a local variable man and not an attribute.
(3) Last but not least, the return result of __init__ is ignored, so
even though you try to return self.man and self.women, nothing happens.
Also, calling the class "Name" is a bad idea, because it doesn't have
anything to do with what the class actually holds, which is a *pair* of
names, one male and one female.
This code should be written as:
class Couple:
def __init__(self):
self.man = "Marcus"
self.woman = "Jasmine"
This creates a class where every instance has its own independent
attributes man and woman.
> class Name:
> man = Marcus
> woman = Jasmine
> return man, woman
Again, did you try this? If you did, you would discover it raises
SyntaxError: you can't include a return statement inside a class,
because it is meaningless.
SyntaxError: 'return' outside function
This should be written as
class Couple:
man = "Marcus"
woman = "Jasmine"
This creates a class where every instance shares the same pair of
attributes.
In this example, the difference is not very great, because strings
cannot be modified in place. If you try to store a new value for the
attribute, Python defaults to creating an independent instance attribute
rather than changing the shared class attribute.
Here is an example that may help show the difference:
class TestAttributes:
a = [1, 2, 3] # Shared, and mutable.
def __init__(self):
self.b = [1, 2, 3] # Not shared.
Now, using this:
>>> x = TestAttributes() # Create a new instance.
>>> y = TestAttributes() # And another one.
>>>
>>> x.a
[1, 2, 3]
>>> y.a
[1, 2, 3]
>>> x.a.append(42) # Modify the SHARED list.
>>> y.a # And all instances see the change!
[1, 2, 3, 42]
>>>
>>> x.b
[1, 2, 3]
>>> x.b.append(999) # Modify the non-shared list.
>>> x.b
[1, 2, 3, 999]
>>> y.b # Other instances are unchanged.
[1, 2, 3]
--
Steven
More information about the Tutor
mailing list