Skip to main content
 首页 » 编程设计

python之Python 模块是否应该导入它们在语义上依赖的模块

2025年05月04日24lyhabc

Python 模块是否应该导入它们在语义上依赖的模块?

例如:

模块a:

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

模块 b:

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

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

请您参考如下方法:

b 在语义上不依赖于任何。

从字面上看,def f 唯一依赖的是 a_instance 生成可调用的属性 .foo。句号。

传入 A() 或 AChild() 甚至 MagicMock 都没有关系。

这就是短语“鸭子打字”的意思。考虑:

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() 的东西,那么就我们而言're concert, 这是一只鸭子!

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 或不同的文件中定义它们,甚至将它们转储为 pickle 并在以后加载它们都没有关系。就我们的功能而言,它们都是鸭子。除了我们的论点具有的属性和行为之外,没有任何语义依赖性。