Python Programming for the Absolute Beginner, 3rd Edition

You can have an object's attributes automatically created and initialized just after it's instantiated through its constructor method. This is a big convenience and something you'll do a lot.

Introducing the Attribute Critter Program

The Attribute Critter program creates a new type of object with an attribute, name. The Critter class has a constructor method that creates and initializes name. The program uses the new attribute so that the critter can offer a more personalized greeting. Figure 8.6 shows the program in action.

Figure 8.6: This time, each Critter object has an attribute name that it uses when it says hi.

The following is the code for the program:

# Attribute Critter # Demonstrates creating and accessing object attributes # Michael Dawson - 3/23/03 class Critter(object): """A virtual pet""" def __init__(self, name): print "A new critter has been born!" self.name = name def __str__(self): rep = "Critter object\n" rep += "name: "+ self.name + "\n" return rep def talk(self): print "Hi. I'm", self.name, "\n" # main crit1 = Critter("Poochie") crit1.talk() crit2 = Critter("Randolph") crit2.talk() print "Printing crit1:" print crit1 print "Directly accessing crit1.name:" print crit1.name raw_input("\n\nPress the enter key to exit.")

Initializing Attributes

The constructor in this program prints the message "A new critter has been born!" just like the constructor in the Constructor Critter program, but the next line of the method does something new. It creates the attribute name for the new object and sets it to the value of the parameter name. So, in the main part of the program, the line:

crit = Critter("Poochie")

results in the creation of a new Critter object with an attribute name set to "Poochie". Finally, the object is assigned to crit.

So that you can understand exactly how this works, I'll reveal what the mysterious self parameter is all about. As the first parameter in every method, self automatically receives a reference to the object invoking the method. This means that, through self, a method can get at the object invoking it and access the object's attributes or methods (or even create new attributes for the object).

HINT

You can name the first parameter in a method header something other than self, but you shouldn't. It's the "Pythonic" way to do things and other programmers will expect it.

So, back in the constructor method, the parameter self automatically receives a reference to the new Critter object while the parameter name receives "Poochie". Then, the line:

self.name = name

creates the attribute name for the object and sets it to the value of name, which is "Poochie".

Back in the main part of the program, the assignment statement assigns this new object to crit. This means that crit refers to a new object with its own attribute called name set to "Poochie". So, a critter has been created with its own name!

The line in the main program:

crit2 = Critter("Randolph")

kicks off the same basic chain of events. But this time, a new Critter object is created with its own attribute name set to "Randolph". And the object is assigned to crit2.

Accessing Attributes

Attributes aren't any good unless you can use them, so I wrote a more personal talk() method that uses a Critter object's name attribute. Now, when a critter says hi, it introduces itself with its name.

I got my first critter to say hi by invoking its talk() method with

crit1.talk()

The talk() method receives the automatically sent reference to the object into its self parameter:

def talk(self):

Then, the print statement displays the text Hi. I'm Poochie by accessing the attribute name of the object through self.name:

print "Hi. I'm", self.name, "\n"

The same basic events occur when I then call the method for my second object:

crit2.talk()

But this time, the talk() method displays the text Hi. I'm Randolph since the name attribute of crit2 is equal to "Randolph".

By default, you can access and modify an object's attributes outside of its class. In the main part of the program, I directly accessed the name attribute of crit1:

print crit1.name

The line prints the string "Poochie". In general, to access an attribute of an object outside the object's class, you can use dot notation. Type the variable name, followed by a dot, followed by the attribute name.

Printing an Object

Normally, if I were to print an object, with the code print crit1, Python would come back with something like the cryptic:

<__main__.Critter object at 0x00A0BA90>

This tells me that I've printed a Critter object in the main part of my program, but doesn't give me any useful information about the object. However, there is a way to change this. By including the special method __str__() in a class definition, you can create a string representation for your objects that will be displayed whenever one is printed. Whatever string you return from the method will be the string that's printed for the object.

The __str__() method I wrote returns a string that includes the value of the object's name attribute. So, when the following line is executed:

print crit1

this, more useful, text appears:

Critter object name: Poochie

TRICK

Even if you never plan to print an object in your program, creating a __str__() method is still not a bad idea. You may find that being able to see the values of an object's attributes helps you understand how a program is working (or not working).

Категории