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