Python : Object Oriented Programming (Getattr)
In this post we will dicuss one use case of the built-in method getattr. We will develop a generic function that uses getattr to print a tabular report from object attributes. By the end of this post you will get a better understanding of getattr.
getattr(object, name[, default])
Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, ‘foobar’) is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
As a first step let us write a simple class Holding
that can hold content from this sample portfolio
files.
**Name,Date,Shares,Price**
HPQ,7/11/2007,100,32.2
IBM,7/12/2007,50,91.9
GE,7/13/2007,150,83.44
CAT,7/14/2007,200,51.23
MSFT,7/15/2007,95,40.37
HPE,7/16/2007,50,65.1
AFL,7/17/2007,100,70.44
class Holding(object):
def __init__(self, name, date, shares, price):
self.name = name
self.date = date
self.shares = shares
self.price = price
Now let us create another class that can load these portfolio csv’s and generate a collection of Holdings
.
class Holdings(object):
'''
This class creates a collection of holding object from
a list of *.csv files. Input param is path to a
folder containing all files or a single file path.
'''
def __init__(self, path):
self.path = path
self.portfolios = []
self.load()
def load(self):
files = []
if os.path.isdir(self.path):
files = glob.glob(os.path.join(self.path,'*.csv'))
else:
files.append(self.path)
for file in files:
with open(file, 'r') as f:
rows = csv.reader(f)
head = next(rows)
for row_no , row in enumerate(rows):
try:
self.portfolios.append(
Holding(name=row[0],
date=row[1],
shares=int(row[2]),
price=float(row[3])))
except ValueError as ve:
print('Ignoring {} {} in {} due to {}'.
format(row_no, row, file, ve))
Now let us write a generic tabular printing function. The input to this function are collection of objects and attribute names to be printed.
def print_objects(objects, columns):
'''
This method prints a table from objects using getattr
:param objects: object list to iterate
:param columns: column names matching attributes of object
'''
# print header
for col in columns:
print('{:>10s}'.format(col), end=' ')
print()
for obj in objects:
for col in columns:
print('{:>10s}'.
format(str(getattr(obj, col))), end=' ')
print()
#program.py
if __name__ == '__main__':
hld = Holdings('stocks')
print_objects(hld.portfolios,
['name', 'date', 'shares', 'price'])
output:
name date shares price
HPQ 7/11/2007 100 32.2
IBM 7/12/2007 50 91.9
GE 7/13/2007 150 83.44
CAT 7/14/2007 200 51.23
MSFT 7/15/2007 95 40.37
HPE 7/16/2007 50 65.1
AFL 7/17/2007 100 70.44
GOOGL 7/11/2008 100 55.2
IBM 7/12/2008 50 91.9
GE 7/13/2008 150 83.44
CAT 7/14/2008 200 51.23
Coding is fun enjoy…