Python如何生成跨模块函数?

Python如何生成跨模块函数?,python,module,global,Python,Module,Global,例如,我希望能够从导入的类调用全局函数 在文件PetStore.py中 class AnimalSound(object): def __init__(self): if 'makenoise' in globals(): self.makenoise = globals()['makenoise'] else: self.makenoise = lambda: 'meow' def __str__(self):

例如,我希望能够从导入的类调用全局函数

在文件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'
我听到的是“喵”而不是“吠”。我尝试过使用中提供的解决方案,但运气不佳。

Python中的“全局”范围是模块范围

import PetStore

PetStore.makenoise = makenoise
Python中的“全局”范围是模块范围

import PetStore

PetStore.makenoise = makenoise
globals();Python中没有内在的“动态范围”——它是词汇范围的,就像几乎所有现代语言一样

获得您想要的效果的可靠、正确的方法是显式地将它用来“制造噪音”的可调用对象传递给
AnimalSound
的初始值设定项:即,类应该是

class AnimalSound(object):
   def __init__(self, makenoise=lambda: 'meow'):
       self.makenoise = makenoise

   def __str__(self):
       return self.makenoise()
sound = AnimalSound(makenoise)
电话应该是

class AnimalSound(object):
   def __init__(self, makenoise=lambda: 'meow'):
       self.makenoise = makenoise

   def __str__(self):
       return self.makenoise()
sound = AnimalSound(makenoise)
有一些可行但不太可靠的解决方案,比如调用方传递自己的
globals()
(但这不必要地限制了可调用方的名称!),甚至像其他答案一样通过隐蔽通道(颤抖)进行通信(如果您在两个单独的模块中根据相同的原则构建了两个
AnimalSound
实例,那么这将是一个潜在的灾难,等等)。但是,“显式优于隐式”,而干净、安全、公开的通信将导致干净、安全、健壮的系统架构:我真诚地建议您选择这条路线。

调用将返回调用所在模块的全局值。
调用将返回调用所在模块的全局值;没有内在的“动态范围”在Python中——它是词汇范围的,就像几乎所有现代语言一样

获得您想要的效果的可靠、正确的方法是显式地将它用来“制造噪音”的可调用对象传递给
AnimalSound
的初始值设定项:即,类应该是

class AnimalSound(object):
   def __init__(self, makenoise=lambda: 'meow'):
       self.makenoise = makenoise

   def __str__(self):
       return self.makenoise()
sound = AnimalSound(makenoise)
电话应该是

class AnimalSound(object):
   def __init__(self, makenoise=lambda: 'meow'):
       self.makenoise = makenoise

   def __str__(self):
       return self.makenoise()
sound = AnimalSound(makenoise)

有一些可行但不太可靠的解决方案,比如调用方传递自己的
globals()
(但这不必要地限制了可调用方的名称!),甚至像其他答案一样通过隐蔽通道(颤抖)进行通信(如果您在两个单独的模块中根据相同的原则构建了两个
AnimalSound
实例,那么这将是一个潜在的灾难,等等)。但是,“显式优于隐式”,而干净、安全、公开的通信将导致干净、安全、健壮的系统体系结构:我真诚地建议您选择这条路线。

谢谢!对于谁给出公认的答案,我有点矛盾,但我想我会接受您的建议,并显式地传递函数。@Evan,当然——我不喜欢@Ignacio关于通过c进行通信的建议公开渠道,但我知道它看起来更简单(直到最初几次你发现自己在调试这种“简单”解决方案的灾难性影响时浪费了数小时或数天,这可能需要数年或数十年的经验).当然,如果你接受了错误的解决方案,但又实施了正确的解决方案,你将永远无法获得真正理解正确解决方案的正确性所需的痛苦经历;-).谢谢!我对谁给出被接受的答案有点矛盾,但我想我会按照你的建议,显式地传递函数。@Evan,当然——我不喜欢@Ignacio建议通过秘密渠道进行沟通,但我知道这看起来更简单(直到最初几次你发现自己在调试这种“简单”解决方案的灾难性后果时浪费了数小时或数天,这可能需要数年或数十年的经验).当然,如果你接受了错误的解决方案,但又实施了正确的解决方案,你将永远无法获得真正理解正确解决方案的正确性所需的痛苦经历;-)。