2016-08-02 49 views
1

Python模块import它们在语义上依赖于哪些模块?Python模块应该导入它们在语义上依赖的模块吗?

例如:

模块a

class A(object): 
    ... 
    def foo(self): 
     ... 

模块b

import a 

def f(a_instance): 
    a_instance.foo() 
    ... 

模块b的第一行是不必要的,严格的说,但我不知道它被认为是好的在Python中的形式?

+9

如果您不是直接使用模块a,那么请勿导入模块a。您的代码正在等待某个类的实例。根据你的方法正在做什么,你不能直接引用模块A.所以'输入'是毫无意义的。 – idjaw

+0

唯一有用的是如果你想做类型提示:'def f(a_instance:a.A)' – acushner

回答

5

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定义它们没关系,或不同的文件,甚至把它们扔掉的泡菜,后来装载它们。就我们的功能而言,它们都是鸭子。除了我们论证所具有的属性和行为之外,没有任何语义依赖关系。