Initial commit
This commit is contained in:
167
Exercises/ex4_1.md
Normal file
167
Exercises/ex4_1.md
Normal file
@@ -0,0 +1,167 @@
|
||||
\[ [Index](index.md) | [Exercise 3.8](ex3_8.md) | [Exercise 4.2](ex4_2.md) \]
|
||||
|
||||
# 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:
|
||||
|
||||
```python
|
||||
>>> 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.
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> goog.__class__
|
||||
... look at output ...
|
||||
>>> ibm.__class__
|
||||
... look at output ...
|
||||
>>>
|
||||
```
|
||||
|
||||
Try calling a method on the instances:
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> SimpleStock.__dict__['cost']
|
||||
... look at output ...
|
||||
>>>
|
||||
```
|
||||
|
||||
Try calling the `cost()` method directly through the dictionary:
|
||||
|
||||
```python
|
||||
>>> 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:
|
||||
|
||||
```python
|
||||
>>> SimpleStock.spam = 42
|
||||
>>> ibm.spam
|
||||
42
|
||||
>>> goog.spam
|
||||
42
|
||||
>>>
|
||||
```
|
||||
|
||||
Observe that `spam` is not part of the instance dictionary.
|
||||
|
||||
```python
|
||||
>>> ibm.__dict__
|
||||
... look at the output ...
|
||||
>>>
|
||||
```
|
||||
|
||||
Instead, it's part of the class dictionary:
|
||||
|
||||
```python
|
||||
>>> SimpleStock.__dict__['spam']
|
||||
42
|
||||
>>>
|
||||
```
|
||||
|
||||
Essentially this is all a class really is--it's a collection of values shared by instances.
|
||||
|
||||
|
||||
\[ [Solution](soln4_1.md) | [Index](index.md) | [Exercise 3.8](ex3_8.md) | [Exercise 4.2](ex4_2.md) \]
|
||||
|
||||
----
|
||||
`>>>` Advanced Python Mastery
|
||||
`...` A course by [dabeaz](https://www.dabeaz.com)
|
||||
`...` Copyright 2007-2023
|
||||
|
||||
. This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)
|
||||
Reference in New Issue
Block a user