http://www2.lib.uchicago.edu/keith/courses/python/class/5/#custom
Customizing Objects
Python Special Methods
Sometimes we may want to customize user-defined classes, such as change the way class objects are initialized, or customize class behavior. Python use some special methods with special names to achieve these.
We discuss a few important special methods to provide an understanding, such as:
__init__()
__str__()
===end
((old version of all chapter))
Initialize class, __init__()
function
In previous Apple
class, it looks like we set the object's value by assigning values to the class variables(name = 'Fuji'
) when defining the class. But in fact, the standard way to initialize an object's values when creating objects is to use __init__( )
function in classes.
__init__()
is a special method, which is called class constructor or initialization method that Python calls automatically when you create a new instance of the class.
__init__
is one of the many method names that have special significance in Python classes. __init__
is short for "initialize". Notice the double underscore both in the beginning and at the end in the name.
All classes should have an __init__()
method as constructor, when you create a class without a constructor, Python automatically creates a default constructor for you that doesn't do anything.
Like all methods in a class, __init__()
always takes at least one argument (also the first argument), self
, which refers to the object itself being created.
Let's rewrite the Apple
class in a more standard way:
class Apple:
def __init__(self)
self.color = 'red'
def say(self):
print("I'm an apple.")
a1 = Apple() # create an Apple instance, a1
print(a1.color) # red
a1.say() # I'm an apple
Remember that self
in a Python class refers to the object itself being created. In the constructor method, __init__
, we define a variable using self.color
to indicate that color
is instance variable, it belongs to an object.
When a class defines an __init__()
method, class instantiation automatically invokes __init__()
for the newly-created class instance, that means when you create a class instance (an object), Python automatically calls __init__
function only once to initializing an object's variables.
So in this example, a1
is a new, initialized Apple instance, it has color 'red' and a method a1.say()
that can print out message "I'm an apple."
Flexible constructor
We can make our class constructor more general by putting extra parameters into it, use __init__(self, parameter1, parameter2...)
for greater flexibility.
class Apple:
def __init__(self, initColor)
self.color = initColor
def say(self):
print("I'm an apple.")
a2 = Apple('red')
print(a2.color) # red
a2.say() # I'm an apple
a3 = Apple('green')
print(a3.color) # green
Here inside __init__()
method, the initColor
refers to the values passed into the constructor, and we assign the value to instance variable using the self
parameter, with the code
self.color = initColor
You can see the initialization function in action when accessing the attributes of objects a2, a3
Attention! notice that we do not explicitly call the __init__
method but pass the arguments in the parentheses following the class name when creating a new instance of the class. This is the special significance of this method.
(More on self)**
When we create an object of a class, such as a2
, an Apple
object, from outside of the class, we refer to its variables or methods using objectName.attributesName such as a2.color, a2.say()
But when we are doing things inside a class, such as using the instance variables or calling other functions defined in the class, we use self.attributesName
.
To be simple, self
is how we refer to things in the class from within itself.
Keep changing Apple
class:
class Apple:
def __init__(self, initColor)
self.color = initColor
def say(self):
print("I'm an apple, my color is ", self.color)
a4 = Apple('red')
print(a4.color) # red
a4.say() # I'm an apple, my color is red
a5 = Apple('pink')
print(a5.color) # pink
a5.say() # I'm an apple, my color is pink
In the new method say()
, we access the instance variable color
using code self.color
Let's see another Dog
class to understand all the above again.
class Dog:
def __init__(self, color, eyeNumber):
self.color = color
self.eyeNumber = eyeNumber
def say(self):
print( 'Woof, Woof, I have ', self.eyeNumber, ' eyes and my color is ', self.color )
t = Dog('brown', 1 )
print(t.color) # brown
t.say() # Woof, Woof, I have 1 eyes and my color is brown
d = Dog('white', 2 )
print(d.eyeNumber) # 2
d.say() # Woof, Woof, I have 2 eyes and my color is white
In function say()
, we access the instance variables color
and eyeNumber
using self.color
and self.eyeNumber
.
t,d
are all instances of Dog
class, they all have the variables and methods defined in the class, class is the blueprint of creating these objects.
Input argument and instance variable have the same name, but they are different variables
Noticed? Here, in the header line we define the __init__
method as taking input parameters color
and eyeNumber
(along with the usual self
).
Inside __init__
, we just create two new instance variables (fields) also called color
and eyeNumber
using code
self.color
self.eyeNumber
.
The self
indicates the object itself, the dotted notation self.variable
allows us to differentiate between the two different kinds of variables: the input parameters and the instance variables. It's common to use the same name for them.
Function calls other function inside the class:
We will use an example to show how to access other methods inside the same class, again, self
is how we refer to things in the class from within itself (such as self.method
).
See example Wallet
class
(remember docstring?) :
Ex. 11.3-2 Wallet.py
# Wallet.py
class Wallet:
"""I have some base money in my Wallet.
I earn more and more money to put in my Wallet."""
def __init__(self, x = 0):
self.total = x
def earn(self, y = 0):
self.total += y
return self.total
def earnTwice(self, z = 0):
self.earn(z)
self.earn(z)
return self.total
myWallet = Wallet(5)
print( myWallet.total ) # 5 (base money)
print( myWallet.earn(10) ) # 15 (total: 5 + 10 )
print( myWallet.earnTwice(20) ) # 55 (total: 5+10+20+20 )
Here in Wallet
class, in the constructor, we define object variable total
and assign a value x to it as the base money.
Then we define the second method earn()
, in earn()
, we refer to object variable total
using self.total
.
The same thing, in the third method addTwice()
, we may call other method (earn()
) by using method attributes of the self
argument, self.earn()
. When we call the methods, we don't need to include the self
argument, only provide value z
for other input argument.
Constructor with default values
Did you notice that in Wallet
class, the constructor __init__(self, x = 0)
is a little different? We set a default value x=0
here. So if we make an instant of Wallet
and forget to provide value for x argument like w = Wallet()
, then w
will have 0 as the base money. If we didn't forget, then the values provided will be assigned to object variable, myWallet = Wallet(5)
, so myWallet
has base money 5.
The previous Apple
and Dog
class can have alternative constructors that have default values:
class Apple:
def __init__(self, initColor = 'white')
self.color = initColor
ap1 = Apple()
print( ap1.color ) # white (default value is working)
a2 = Apple('green')
print( a2.color ) # green
class Dog:
def __init__(self, color = 'clear', eyeNumber = 0):
self.color = color
self.eyeNumber = eyeNumber
d1 = Dog()
print( d1.color, d1.eyeNumber ) # clear, 0 ( a glass dog with no eyes! Any thing is possible in Python )
d2 = Dog('red', 5)
print(d2.color, d2.eyeNumber) # red, 5 (Dose Clifford have 5 eyes?)
===== end
http://www.diveintopython3.net/iterators.html#divingin
(above link:) The init() method is called immediately after an instance of the class is created. It would be tempting — but technically incorrect — to call this the “constructor” of the class. It’s tempting, because it looks like a C++ constructor (by convention, the init() method is the first method defined for the class), acts like one (it’s the first piece of code executed in a newly created instance of the class), and even sounds like one. Incorrect, because the object has already been constructed by the time the init() method is called, and you already have a valid reference to the new instance of the class. The first argument of every class method, including the init() method, is always a reference to the current instance of the class. By convention, this argument is named self. This argument fills the role of the reserved word this in c++ or Java, but self is not a reserved word in Python, merely a naming convention. Nonetheless, please don’t call it anything but self; this is a very strong convention.
In all class methods, self refers to the instance whose method was called. But in the specific case of the init() method, the instance whose method was called is also the newly created object. Although you need to specify self explicitly when defining the method, you do not specify it when calling the method; Python will add it for you automatically.
===
Many classes like to create objects in a known initial state. Therefore a class may define a special method named init(), like this:
def __init__(self):
self.data = []
When a class defines an init() method, class instantiation automatically invokes init() for the newly-created class instance. So in this example, a new, initialized instance can be obtained by:
x = MyClass() Of course, the init() method may have arguments for greater flexibility. In that case, arguments given to the class instantiation operator are passed on to init(). For example,
class Complex: ... def init(self, realpart, imagpart): ... self.r = realpart ... self.i = imagpart ... x = Complex(3.0,-4.5) x.r, x.i (3.0, -4.5)