Выбрать главу

that object by using a period and the name of the class to call, with any parameters passed inside parentheses.

Class and Object Variables

Each object has its own set of functions and variables, and you can manipulate those variables independent of objects of the same type. Additionally, some class variables are set to a default value for all classes and can also be manipulated globally.

This script demonstrates two objects of the dog class being created, each with its own name:

class dog(object):

 name = "Lassie"

 def bark(self):

  print self.name + " says 'Woof!'"

 def setName(self, name):

  self.name = name

fluffy = dog()

fluffy.bark()

poppy = dog()

poppy.setName("Poppy")

poppy.bark()

That outputs the following:

Lassie says 'Woof!'

Poppy says 'Woof!'

Each dog starts with the name Lassie, but it gets customized. Keep in mind that Python assigns by reference by default, meaning each object has a reference to the class's name variable, and as you assign that with the setName() method, that reference is lost. What this means is that any references you do not change can be manipulated globally. Thus, if you change a class's variable, it also changes in all instances of that class that have not set their own value for that variable. For example:

class dog(object):

 name = "Lassie"

 color = "brown"

fluffy = dog()

poppy = dog()

print fluffy.color

dog.color = "black"

print poppy.color

poppy.color = "yellow"

print fluffy.color

print poppy.color

So, the default color of dogs is brown — both the fluffy and poppy dog objects start off as brown. Then, with dog.color, the default color is set to black, and because neither of the two objects has set its own color value, they are updated to be black. The third to last line uses poppy.color to set a custom color value for the poppy object — poppy becomes yellow, but fluffy and the dog class in general remain black.

Constructors and Destructors

To help you automate the creation and deletion of objects, you can easily override two default methods: __init__ and __del__. These are the methods called by Python when a class is being instantiated and freed, known as the constructor and destructor, respectively.

Having a custom constructor is great when you need to accept a set of parameters for each object being created. For example, you might want each dog to have its own name on creation, and you could implement that with this code:

class dog(object):

 def __init__(self, name):

  self.name = name

fluffy = dog("Fluffy")

print fluffy.name

If you do not provide a name parameter when creating the dog object, Python reports an error and stops. You can, of course, ask for as many constructor parameters as you want, although it is usually better to ask for only the ones you need and have other functions fill in the rest.

On the other side of things is the destructor method, which allows you to have more control over what happens when an object is destroyed. Using the two, you can show the life cycle of an object by printing messages when it is created and deleted:

class dog(object):

 def __init__(self, name):

  self.name = name print

  self.name + " is alive!"

 def __del__(self):

  print self.name + " is no more!"

fluffy = dog("Fluffy")

The destructor is there to give you the chance to free up resources allocated to the object or perhaps log something to a file.

Class Inheritance

Python allows you to reuse your code by inheriting one class from one or more others. For example, cars, trucks, and motorbikes are all vehicles, and so share a number of similar properties. In that scenario, you would not want to have to copy and paste functions between them; it would be smarter (and easier!) to have a vehicle class that defines all the shared functionality and then inherit each vehicle from that.

Consider the following code:

class car(object):

 color = "black"

 speed = 0

 def accelerateTo(self, speed):

  self.speed = speed

 def setColor(self, color):

  self.color = color

mycar = car()

print mycar.color

This creates a car class with a default color and also provides a setColor() function so that people can change their own colors. Now, what do you drive to work? Is it a car? Sure it is, but chances are it is a Ford, or a Dodge, or a Jeep, or some other make — you don't get cars without a make. On the other hand, you do not want to have to define a class Ford, give it the methods accelerateTo(), setColor(), and however many other methods a basic car has and then do exactly the same thing for Ferrari, Nissan, and so on.

The solution is to use inheritance: Define a car class that contains all the shared functions and variables of all the makes and then inherit from that. In Python, you do this by putting the name of the class from which to inherit inside parentheses in the class declaration, like this:

class car(object):

 color = "black"

 speed = 0

 def accelerateTo(self, speed):

  self.speed = speed

 def setColor(self, color):

  self.color = color

class ford(car): pass

class nissan(car): pass

mycar = ford()

print mycar.color

The pass directive is an empty statement — it means the class contains nothing new. However, because the ford and nissan classes inherit from the car class, they get color, speed, accelerateTo(), and setColor() provided by their parent class. Note that you do not need object after the classnames for ford and nissan because they are inherited from an existing class: car.

By default, Python gives you all the methods the parent class has, but you can override that by providing new implementations for the classes that need them. For example:

class modelt(car):

 def setColor(self, color):

  print "Sorry, Model Ts come only in black!"

myford = ford()

ford.setColor("green")