5.1 KiB
[ Index | Exercise 3.5 | Exercise 3.7 ]
Exercise 3.6
Objectives:
- Learn how to customize the behavior of objects by redefining special methods.
- Change the way that user-defined objects get printed
- Make objects comparable
- Create a context manager
Files Created: None
Files Modified: stock.py
(a) Better output for representing objects
All Python objects have two string representations. The first
representation is created by string conversion via str()
(which is called by print
). The string representation is
usually a nicely formatted version of the object meant for humans. The
second representation is a code representation of the object created by
repr()
(or simply by viewing a value in the interactive
shell). The code representation typically shows you the code that you
have to type to get the object. Here is an example that illustrates
using dates:
>>> from datetime import date
>>> d = date(2008, 7, 5)
>>> print(d) # uses str()
2008-07-05
>>> d # uses repr()
2008, 7, 5)
datetime.date(>>>
There are several techniques for obtaining the repr()
string in output:
>>> print('The date is', repr(d))
is datetime.date(2008, 7, 5)
The date >>> print(f'The date is {d!r}')
is datetime.date(2008, 7, 5)
The date >>> print('The date is %r' % d)
is datetime.date(2008, 7, 5)
The date >>>
Modify the Stock
object that you’ve created so that the
__repr__()
method produces more useful output. For
example:
>>> goog = Stock('GOOG', 100, 490.10)
>>> goog
'GOOG', 100, 490.1)
Stock(>>>
See what happens when you read a portfolio of stocks and view the resulting list after you have made these changes. For example:
>>> import stock, reader
>>> portfolio = reader.read_csv_as_instances('Data/portfolio.csv', stock.Stock)
>>> portfolio
'AA', 100, 32.2), Stock('IBM', 50, 91.1), Stock('CAT', 150, 83.44), Stock('MSFT', 200, 51.23),
[Stock('GE', 95, 40.37), Stock('MSFT', 50, 65.1), Stock('IBM', 100, 70.44)]
Stock(>>>
(b) Making objects comparable
What happens if you create two identical Stock
objects
and try to compare them? Find out:
>>> a = Stock('GOOG', 100, 490.1)
>>> b = Stock('GOOG', 100, 490.1)
>>> a == b
False
>>>
You can fix this by giving the Stock
class an
__eq__()
method. For example:
class Stock:
...def __eq__(self, other):
return isinstance(other, Stock) and ((self.name, self.shares, self.price) ==
(other.name, other.shares, other.price)) ...
Make this change and try comparing two objects again.
(c) A Context Manager
In link:ex3_5.html[Exercise 3.5], you made it possible for users to make nicely formatted tables. For example:
>>> from tableformat import create_formatter
>>> formatter = create_formatter('text')
>>> print_table(portfolio, ['name','shares','price'], formatter)
name shares price---------- ---------- ----------
100 32.2
AA 50 91.1
IBM 150 83.44
CAT 200 51.23
MSFT 95 40.37
GE 50 65.1
MSFT 100 70.44
IBM >>>
One issue with the code is that all tables are printed to standard
out (sys.stdout
). Suppose you wanted to redirect the output
to a file or some other location. In the big picture, you might modify
all of the table formatting code to allow a different output file.
However, in a pinch, you could also solve this with a context
manager.
Define the following context manager:
>>> import sys
>>> class redirect_stdout:
def __init__(self, out_file):
self.out_file = out_file
def __enter__(self):
self.stdout = sys.stdout
= self.out_file
sys.stdout return self.out_file
def __exit__(self, ty, val, tb):
= self.stdout sys.stdout
This context manager works by making a temporary patch to
sys.stdout
to cause all output to redirect to a different
file. On exit, the patch is reverted. Try it out:
>>> from tableformat import create_formatter
>>> formatter = create_formatter('text')
>>> with redirect_stdout(open('out.txt', 'w')) as file:
'name','shares','price', formatter)
tableformat.print_table(portfolio, [file.close()
>>> # Inspect the file
>>> print(open('out.txt').read())
name shares price---------- ---------- ----------
100 32.2
AA 50 91.1
IBM 150 83.44
CAT 200 51.23
MSFT 95 40.37
GE 50 65.1
MSFT 100 70.44
IBM >>>
[ Solution | Index | Exercise 3.5 | Exercise 3.7 ]
>>>
Advanced Python Mastery
...
A course by dabeaz
...
Copyright 2007-2023
.
This work is licensed under a Creative Commons
Attribution-ShareAlike 4.0 International License