Skip to content

Latest commit

 

History

History
167 lines (125 loc) · 3.72 KB

ex4_1.md

File metadata and controls

167 lines (125 loc) · 3.72 KB

[ Index | Exercise 3.8 | Exercise 4.2 ]

Exercise 4.1

Objectives:

  • Learn more about how objects are represented.
  • Learn how attribute assignment and lookup works.
  • Better understand the role of a class definition

Files Created: None

Files Modified: None

Start this exercise, by going back to a simple version of the Stock class you created. At the interactive prompt, define a new class called SimpleStock that looks like this:

>>> class SimpleStock:
        def __init__(self, name, shares, price):
            self.name = name
            self.shares = shares
            self.price = price
        def cost(self):
            return self.shares * self.price

>>>

Once you have defined this class, create a few instances.

>>> goog = SimpleStock('GOOG',100,490.10)
>>> ibm  = SimpleStock('IBM',50, 91.23)
>>>

(a) Representation of Instances

At the interactive shell, inspect the underlying dictionaries of the two instances you created:

>>> goog.__dict__
... look at the output ...
>>> ibm.__dict__
... look at the output ...
>>>

(b) Modification of Instance Data

Try setting a new attribute on one of the above instances:

>>> goog.date = "6/11/2007"
>>> goog.__dict__
... look at output ...
>>> ibm.__dict__
... look at output ...
>>>

In the above output, you'll notice that the goog instance has a attribute date whereas the ibm instance does not. It is important to note that Python really doesn't place any restrictions on attributes. For example, the attributes of an instance are not limited to those set up in the __init__() method.

Instead of setting an attribute, try placing a new value directly into the __dict__ object:

>>> goog.__dict__['time'] = '9:45am'
>>> goog.time
'9:45am'
>>>

Here, you really notice the fact that an instance is a layer on top of a dictionary.

(c) The role of classes

The definitions that make up a class definition are shared by all instances of that class. Notice, that all instances have a link back to their associated class:

>>> goog.__class__
... look at output ...
>>> ibm.__class__
... look at output ...
>>> 

Try calling a method on the instances:

>>> goog.cost()
49010.0
>>> ibm.cost()
4561.5
>>>

Notice that the name 'cost' is not defined in either goog.__dict__ or ibm.__dict__. Instead, it is being supplied by the class dictionary. Try this:

>>> SimpleStock.__dict__['cost']
... look at output ...
>>>

Try calling the cost() method directly through the dictionary:

>>> SimpleStock.__dict__['cost'](goog)
49010.00
>>> SimpleStock.__dict__['cost'](ibm)
4561.5
>>>

Notice how you are calling the function defined in the class definition and how the self argument gets the instance.

If you add a new value to the class, it becomes a class variable that's visible to all instances. Try it:

>>> SimpleStock.spam = 42
>>> ibm.spam
42
>>> goog.spam
42
>>>

Observe that spam is not part of the instance dictionary.

>>> ibm.__dict__
... look at the output ...
>>>

Instead, it's part of the class dictionary:

>>> SimpleStock.__dict__['spam']
42
>>>

Essentially this is all a class really is--it's a collection of values shared by instances.

[ Solution | Index | Exercise 3.8 | Exercise 4.2 ]


>>> Advanced Python Mastery
... A course by dabeaz
... Copyright 2007-2023

. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License