Python:如何访问父模块中声明的变量

13 投票
2 回答
13378 浏览
提问于 2025-04-16 00:12

根据Python文档中的结构:

sound/
  __init__.py
  effects/
          __init__.py
          echo.py
          surround.py
          reverse.py

假设我想要 import sound.effects 并获取可用效果的列表。我可以通过在 sound.effects 中声明一个模块级变量,然后在每个.py文件被导入时将效果添加到这个变量中来实现。所以 sound/effects/__init__.py 可能看起来像这样:

effectList = []
import echo
import surround   # Could write code to import *.py instead
...

现在,从我的主代码中,我可以访问 sound.effects.effectList 来获取效果列表,但我该如何在 echo.py 中访问 effectList 来实际添加效果呢?我在尝试获取这个变量的访问权限时遇到了困难:

# None of these work :-(
# from . import self
# from .. import effects
# import sound.effects

sound.effect.effectList.append({'name': 'echo'})

2 个回答

3

我觉得你应该把“提供可用性”的工作留给__init__.py文件,这个文件在effects包里面,而不是让所有模块都自动填充effectList。我想到几个原因。

  1. 如果你真的能让这个工作正常运行,你只能通过包来导入效果,而不能直接导入(因为它们会在导入的模块中期待一个effectList)。
  2. 你需要在每个你写的效果里手动添加,这样很麻烦。如果你在__init__.py里实现一个类似import *.py的功能,把当前目录下的所有东西都加载进来,那就简单多了。

在你的__init__.py里可以这样写。

import os, glob

effectslist = []

for i in glob.glob("*.py"):
    if i == "__init__.py":
        next
    print "Attempting to import %s"%i
    try:
        mod = __import__(os.path.splitext(i)[0])
        effectslist.append(mod)
    except ImportError,m:
        print "Error while importing %s - %s"%(i,m)
10

在这种情况下,人们通常会在模块中创建一个叫做common.py的文件。

sound/
  __init__.py
  effect/
          __init__.py
          common.py
          echo.py
          surround.py
          reverse.py

然后你把代码从__init__.py文件移动到common.py文件里:

effectList = []
import echo
import surround   # Could write code to import *.py instead
...

__init__.py文件里,你会看到这样的内容:

from common import *

所以现在在echo.py文件里,你会看到这样的内容:

import common
common.effectList.append({'name': 'echo'})

任何需要使用声音的地方都会这样来引用它:

import sound.effect

for effect_name,effect in sound.effect.effectlist.items():
    #....

我自己刚开始使用这个方法,但我相信在Python社区里这是个很常见的做法。

撰写回答