如果我有一个名为BaseData
的抽象基类,其函数update
在其子类中被覆盖了不同的功能,我可以使用如下函数,我希望函数在将任何Child Class作为参数,并为相应的Child Class调用update
函数。
def date_func(BaseData, time):
result = BaseData.update(time)
lastrow = len(result.index)
return result['Time'].iloc[lastrow],result['Time'].iloc[lastrow-100]
答案 0 :(得分:2)
当然可以。 Python不关心,因为它不进行任何类型检查。
实际上,您可以使用提供兼容接口的任何类型,而不管该实例是否来自BaseData
。
答案 1 :(得分:0)
包含ABC名称作为参数名称不会将其仅限于ABC的子类。它所做的就是创建该名称的参数。
任何类型的任何对象都可以作为参数传递给任何函数或方法。任何对象 - 在这种情况下 - 没有update()
将导致AttributeError
被引发,但如果参数有一个update()
方法可以接受给定的一个参数,它不会引起问题。
如果您想确定第一个参数是BaseData
的子类,请按照下列步骤操作:
data
。这将使参数的名称不是阴影(“在此上下文中替换”)实际的BaseData
类if isinstance(data, BaseData):
,标记已存在的所有内容。else
子句。如果不这样做,那么当类型检查失败时,将只返回None
。现在您已经知道如何做您所要求的事情,您应该知道这样做几乎没有值得做的事情。同样,任何满足所需“协议”的对象都可以工作,并且不一定必须是ABC的子类。
这遵循python的原则“请求宽恕而非许可”(或EAFTP),这让我们假设传递参数的人给出了兼容类型之一。如果您担心某人提供错误类型的可能性,那么您可以将代码包装在try-catch
块中,以处理在出错时引发的异常。这就是我们“请求宽恕”的方式。
通常,如果您要进行类型检查,那是因为您已准备好处理不同的协议集,并且定义这些协议的ABC也(最好)定义__subclasshook__()
以便它不会只是检查该类是否是“已注册”的子类,而是遵循规定的协议。