开发者

Python How to make a cross-module function?

开发者 https://www.devze.com 2023-01-01 01:35 出处:网络
I want to be able to call a global function from an imported class, for example In file PetStore.py class AnimalSound(object):

I want to be able to call a global function from an imported class, for example

In file PetStore.py

class AnimalSound(object):
   def __init__(self):
      if 'makenoise' in globals():
         self.makenoise = globals()['makenoise']
      else:
         self.makenoise = lambda: 'meow'

   def __str__(sel开发者_如何学运维f):
      return self.makenoise()

Then when I test in the Python Interpreter

>>> def makenoise():
...    return 'bark'
...
>>> from PetStore import AnimalSound
>>> sound = AnimalSound()
>>> sound.makenoise()
'meow'

I get a 'meow' instead of 'bark'. I have tried using the solutions provided in python-how-to-make-a-cross-module-variable with no luck.


The globals() call returns the globals of the module in which the call is lexically located; there is no intrinsic "dynamic scoping" in Python -- it's lexically scoped, like just about every modern language.

The solid, proper way to obtain the effect you desire is to explicitly pass to the initializer of AnimalSound the callable it's supposed to use to "make noise": i.e., the class should be

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

   def __str__(self):
       return self.makenoise()

and the call should be

sound = AnimalSound(makenoise)

There are practicable but less-sound solutions, such as the caller passing its own globals() (but that needlessly constrains the name of the callable!), or even (shudder) communicating via covert channels like the other answer advocates (that would be a potential disaster if you had two instantiations of AnimalSound built according to the same principle in two separate modules, etc, etc). But, "explicit is better than implicit", and clean, safe, overt communication leads to clean, safe, robust system architectures: I earnestly recommend you choose this route.


"Global" scope in Python is Module scope.

import PetStore

PetStore.makenoise = makenoise
0

精彩评论

暂无评论...
验证码 换一张
取 消