b
語義上取決於什麼都沒有。
字面上,def f
唯一依賴的是a_instance
產生的屬性.foo
是可調用的。句號。
不要緊,如果你通過A()
或AChild()
甚至MagicMock
。
這就是「duck typing」的意思。試想一下:
def is_a_duck(duck_candidate):
duck_candidate.looks_like_a_duck()
duck_candidate.walks_like_a_duck()
duck_candidate.quacks_like_a_duck()
print('This is a duck')
return True
如果你創造的東西,.looks_like_a_duck()
和.walks_like_a_duck()
和.quacks_like_a_duck()
,然後就我們的演唱會,這是一個鴨子!
class Person:
def looks_like_a_duck(self): pass
def walks_like_a_duck(self): pass
def quacks_like_a_duck(self): pass
class FakeDuck:
def looks_like_a_duck(self): pass
def walks_like_a_duck(self): pass
def quacks_like_a_duck(self): print('Quack quack quack')
def funcy_duck():
funcy_duck.looks_like_a_duck = lambda: None
funcy_duck.walks_like_a_duck = lambda: None
funcy_duck.quacks_like_a_duck = lambda: None
return funcy_duck
print(is_a_duck(Person())
print(is_a_duck(FakeDuck())
try:
print(is_a_duck(funcy_duck))
except AttributeError:
print('not a duck yet')
funcy_duck()
print(is_a_duck(funcy_duck))
這些都是鴨子 - 如果你在ducks.py
定義它們沒關係,或不同的文件,甚至把它們扔掉的泡菜,後來裝載它們。就我們的功能而言,它們都是鴨子。除了我們論證所具有的屬性和行爲之外,沒有任何語義依賴關係。
如果您不是直接使用模塊a,那麼請勿導入模塊a。您的代碼正在等待某個類的實例。根據你的方法正在做什麼,你不能直接引用模塊A.所以'輸入'是毫無意義的。 – idjaw
唯一有用的是如果你想做類型提示:'def f(a_instance:a.A)' – acushner