我认为使用isinstance()
不会被认为是pythonic,人们建议例如使用hasattr()
。
我想知道最好的方法是记录使用hasattr()
的函数的正确用法。
实施例:
我从不同的网站(例如雅虎财经,谷歌财经)获得股票数据,并且有GoogleFinanceData
和YahooFinanceData
类,它们都有方法get_stock(date)
。
还有一个功能可以比较两种股票的价值:
def compare_stocks(stock1,stock2,date):
if hasattr(stock1,'get_stock') and hasattr(stock2,'get_stock'):
if stock1.get_stock(date) < stock2.get_stock(date):
print "stock1 < stock2"
else:
print "stock1 > stock2"
该功能使用如下:
compare_stocks(GoogleFinanceData('Microsoft'),YahooFinanceData('Apple'),'2012-03-14')
它不是这样使用的:
compare_stocks('Tree',123,'bla')
问题是:如何让人们知道他们可以为stock1
和stock2
使用哪些课程?我应该写一个类似"stock1 and stock2 ought to have a method get_stock"
的文档字符串,人们必须自己查看源代码吗?或者我将所有正确的类放入一个模块并在docstring中引用该文件?
答案 0 :(得分:3)
如果您所做的只是使用*FinanceData
个实例调用该函数,我甚至不打算使用get_stock
方法进行测试;传递其他任何内容都是错误的,如果有人传入字符串,该函数应该会中断。
换句话说,只需将您的函数记录为期望get_stock()
方法,而不是测试。 Duck输入用于需要接受明显不同类型输入的代码,而不是仅适用于一种特定类型的代码。
答案 1 :(得分:1)
做你的建议,放在传递参数的docstring中应该有一个get_stock函数,这就是你的函数所需要的,列出类很糟糕,因为代码可能适用于派生或其他类,当它适合某人时。< / p>
答案 2 :(得分:1)
我没有看到isinstance()
的使用是什么,我会创建一个基类并引用基类的文档。
def compare_stocks(stock1, stock2, date):
""" Compares stock data of two FinanceData objects at a certain time. """
if isinstance(stock1, FinanceData) and isinstance(stock2, FinanceData):
return 'comparison'
class FinanceData(object):
def get_stock(self, date):
""" Returns stock data in format XX, expects parameter date in format YY """
raise NotImplementedError
class GoogleFinanceData(FinanceData):
def get_stock(self, date):
""" Implements FinanceData.get_stock() """
return 'important data'
如你所见,我不在这里使用鸭子打字,但由于你在文档方面提出了这个问题,我认为这是一种更清晰的可读性方法。每当另一位开发人员看到compare_stocks
函数或get_stock
方法时,他就确切地知道他必须在哪里寻找有关功能,数据结构或实现细节的更多信息。