目录 | 上一节 (3.5 主模块) | 下一节 (4 类)python
本节,咱们从新考虑以前所作的设计决策。git
考虑如下两个返回相同输出的程序。github
# Provide a filename def read_data(filename): records = [] with open(filename) as f: for line in f: ... records.append(r) return records d = read_data('file.csv')
# Provide lines def read_data(lines): records = [] for line in lines: ... records.append(r) return records with open('file.csv') as f: d = read_data(f)
在计算机程序设计中,鸭子类型 用于肯定一个对象是否可用于特定目的。这是 鸭子测试 的一种应用。segmentfault
若是它看起来像鸭子、游泳像鸭子、叫声像鸭子,那么它可能就是只鸭子。
上述第二个 read_data()
函数接受任何可迭代对象,而不只是文件行。安全
def read_data(lines): records = [] for line in lines: ... records.append(r) return records
这意味着咱们能够使用它处理其它的行(lines)。app
# A CSV file lines = open('data.csv') data = read_data(lines) # A zipped file lines = gzip.open('data.csv.gz','rt') data = read_data(lines) # The Standard Input lines = sys.stdin data = read_data(lines) # A list of strings lines = ['ACME,50,91.1','IBM,75,123.45', ... ] data = read_data(lines)
这种设计具备很大的灵活性。ide
问题:咱们应该拥抱仍是反对这种灵活性?函数
一般,拥抱灵活性能够更好的服务于代码库。不要限制你的选择,灵活性大,带来的威力也大。测试
如今,你已经建立了一个包含 parse_csv()
函数的 fileparse.py
文件。parse_csv()
函数像下面这样工做:翻译
>>> import fileparse >>> portfolio = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float]) >>>
虽然函数接受的是一个文件名,可是,你能够使代码更具灵活性。请求修改函数,以便它能够接受任何类文件或者可迭代对象。例如:
>>> import fileparse >>> import gzip >>> with gzip.open('Data/portfolio.csv.gz', 'rt') as file: ... port = fileparse.parse_csv(file, types=[str,int,float]) ... >>> lines = ['name,shares,price', 'AA,100,34.23', 'IBM,50,91.1', 'HPE,75,45.1'] >>> port = fileparse.parse_csv(lines, types=[str,int,float]) >>>
在新的代码中,若是像之前同样传递一个文件名会发生什么?
>>> port = fileparse.parse_csv('Data/portfolio.csv', types=[str,int,float]) >>> port ... look at output (it should be crazy) ... >>>
正如上面代码显示的那样,这可能带来意想不到的结果,因此,修改的时候须要当心一些。你能够添加安全检查来避免这种状况吗?
请修复 report.py
文件中的 read_portfolio()
和 read_prices()
函数。以便它们能够使用修改后的 parse_csv()
函数。这应该只涉及较小的修改。以后,report.py
和 pcost.py
程序应可以像以往同样工做。
目录 | 上一节 (3.5 主模块) | 下一节 (4 类)
注:完整翻译见 https://github.com/codists/pr...