2014-07-17 64 views
0

這更多的是Python 2的問題,但我很好奇Python 3是否有任何不同。我注意到,當在類上創建某些方法時(無論它們是否是新風格),Python自動決定這些類是來自collections模塊的某些類的實例。我下面的例子用collections.Callable演示了這個。自動繼承自collections.Callable(和其他類)是如何工作的?

>>> import collections 
>>> class A: 
     def __call__(self): 
       print "A" 


>>> a = A() 
>>> isinstance(a, collections.Callable) 
True 
>>> class A(object): 
     def __call__(self): 
       print "A" 


>>> a = A() 
>>> isinstance(a, collections.Callable) 
True 
>>> class A(object): 
     pass 

>>> a = A() 
>>> isinstance(a, collections.Callable) 
False 
>>> class A: 
     pass 

>>> a = A() 
>>> isinstance(a, collections.Callable) 
False 

你會發現,我沒有明確做出的任何這些類的從collections.Callable繼承,但由於某些原因,他們都只要他們創造一個__call__方法做。 這是爲了一個特定的目的而完成的,並且它在某個地方被很好地定義了嗎? Python是否自動爲特定的基類提供類來定義方法或者是其他的事情?

對於collections.Iterable和__iter__方法以及一些其他特殊方法,您也會得到類似的結果。

+0

請參閱https://docs.python.org/2/library/abc.html,特別是[本節](https://docs.python.org/2/library/abc.html#abc.ABCMeta .__ subclasshook__)和[this](https://docs.python.org/2/library/collections.html#collections-abstract-base-classes)。 – BrenBarn

回答

0

ABCMeta class implements hooks to customize instance and subclass checks;提供了__instancecheck__()__subclasscheck__()

這些掛鉤委託給ABCMeta.__subclasshook__() method:子類

__subclasshook__(subclass)

檢查是否被認爲是這個ABC的子類。這意味着您可以進一步自定義issubclass的行爲,而無需在要考慮ABC的子類的每個類上調用register()

這個鉤子然後可以檢查給定的子類是否實現了預期的方法;爲Callableimplementation只需簡單地查看是否有一個__call__方法本:

@classmethod 
def __subclasshook__(cls, C): 
    if cls is Callable: 
     if _hasattr(C, "__call__"): 
      return True 
    return NotImplemented 

這被限制在特定類Callable;子類將不得不實現他們自己的版本,因爲你很可能會添加方法。