0

我看到它不被认为是 pythonic 使用isinstance(),人们建议例如使用hasattr().

我想知道最好的方法是记录正确使用使用hasattr().

示例:我从不同的网站(例如 Yahoo Finance、Google Finance)获取股票数据,并且有一些类GoogleFinanceDataYahooFinanceData它们都有一个方法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"并且人们必须自己查看源代码?或者我是否将所有正确的类放入一个模块并在文档字符串中引用该文件?

4

3 回答 3

3

如果您所做的只是用*FinanceData实例调用函数,我什至不会费心测试该get_stock方法;传入其他任何内容都是错误的,如果有人传入字符串,该函数应该会中断。

换句话说,只需将您的函数记录为期望get_stock()方法,而根本不进行测试。Duck typing 适用于需要接受明显不同类型输入的代码,而不适用于仅适用于一种特定类型的代码。

于 2012-09-12T10:10:58.270 回答
1

做你的建议,放入传递参数的文档字符串应该有一个 get_stock 函数,这就是你的函数所需要的,列出类是不好的,因为当它适合某人时,代码很可能与派生类或其他类一起使用。

于 2012-09-12T10:00:08.653 回答
1

我没有看到关于使用的 unpythonic 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方法时,他都知道必须在哪里寻找有关功能、数据结构或实现细节的更多信息。

于 2012-09-12T10:11:05.947 回答