Python 如何实现跨模块函数?
我想从一个导入的类中调用一个全局函数,比如说
在文件 PetStore.py 中
class AnimalSound(object):
def __init__(self):
if 'makenoise' in globals():
self.makenoise = globals()['makenoise']
else:
self.makenoise = lambda: 'meow'
def __str__(self):
return self.makenoise()
然后当我在 Python 解释器中测试时
>>> def makenoise():
... return 'bark'
...
>>> from PetStore import AnimalSound
>>> sound = AnimalSound()
>>> sound.makenoise()
'meow'
我得到的是 'meow' 而不是 'bark'。我试过在 python-how-to-make-a-cross-module-variable 中提供的解决方案,但没有成功。
2 个回答
2
在Python中,“全局”范围其实指的是模块范围。
import PetStore
PetStore.makenoise = makenoise
5
globals()
这个函数会返回调用它的模块中的全局变量。Python没有所谓的“动态作用域”,它是基于代码位置的作用域,这和大多数现代编程语言是一样的。
想要实现你想要的效果,最好的方法是明确地把一个可以调用的函数传给AnimalSound
的初始化器,也就是说,类应该是
class AnimalSound(object):
def __init__(self, makenoise=lambda: 'meow'):
self.makenoise = makenoise
def __str__(self):
return self.makenoise()
而调用应该是
sound = AnimalSound(makenoise)
还有一些可行但不太好的解决方案,比如调用者传自己的globals()
(但这样会限制可调用函数的名称!),甚至(让人不安)通过隐秘的方式进行沟通,就像其他答案提到的那样(如果你在两个不同的模块中根据同样的原则创建了两个AnimalSound
的实例,那可能会出大问题)。不过,“明确比隐含更好”,清晰、安全、直接的沟通会导致更干净、更安全、更稳健的系统架构:我真心建议你选择这个方法。