我试图访问模块的数据,从其内部 __main__.py.

结构如下:

mymod/
    __init__.py
    __main__.py

现在,如果我获得一个变量 __init__.py 是这样的:

__all__ = ['foo']
foo = {'bar': 'baz'}

我如何可以访问 foo__main__.py?

有帮助吗?

解决方案

你需要或有软件包已经在 sys.path, 添加的含有目录 mymodsys.path__main__.py, 或者使用 -m 开关。

添加 mymod 路径看起来像这样的东西(在 __main__.py):

import sys
import os
path = os.path.dirname(sys.modules[__name__].__file__)
path = os.path.join(path, '..')
sys.path.insert(0, path)
from myprog import function_you_referenced_from_init_file

使用 -m 开关会,如:

python -m mymod

看看 这个答案 更多的讨论。

其他提示

问题是我遇到最有这种类型的事情是,我常常想要跑的 __init__.py 作为一个文件脚本,以测试特色,但这些不应被当运行装载的包装。没一个有用的解决办法用于不同的执行之间的路径 python <package>/__init__.pypython -m <package>.

  • $ python -m <module> 执行 <package>/__main__.py. __init__.py 不是装载。
  • $ python <package>/__init__.py 只需执行的脚本 __init__.py 像一个正常的脚本。


的问题

当我们想要的 __init__.py 有一个 if __name__ == '__main__': ... 条款, 使用 东西从 __main__.py.我们不能进 __main__.py 因为它总是会导入 __main__.pyc 从口译员的路径。(除非...我们绝对路径进攻击,这可能会导致很多其他的烂摊子).


该解决方案 一个解决方案:)

使用两个脚本文件模块的 __main__:

<package>/
         __init__.py
         __main__.py
         main.py

# __init__.py

# ...
# some code, including module methods and __all__ definitions

__all__ = ['foo', 'bar']
bar = {'key': 'value'}
def foo():
    return bar
# ...
if __name__ == '__main__':
    from main import main
    main.main()

# __main__.py

# some code...such as:
import sys
if (len(sys.argv) > 1 and sys.argv[1].lower() == 'option1'):
    from main import main()
    main('option1')
elif (len(sys.argv) > 1 and sys.argv[1].lower() == 'option2'):
    from main import main()
    main('option2')
else:
    # do something else?
    print 'invalid option. please use "python -m <package> option1|option2"'

# main.py

def main(opt = None):
    if opt == 'option1':
        from __init__ import foo
        print foo()
    elif opt == 'option2':
        from __init__ import bar
        print bar.keys()
    elif opt is None:
        print 'called from __init__'

进口中 main.py 很可能不理想的情况下,我们正在运行 __init__.py, 我们重新装入当地范围的另一个模块,尽管具有装他们 __init__.py 已经,但是明确载入应该避免循环的装载。如果你做的整个负载 __init__ 模块再次在您的 main.py, 它将不能装作 __main__, ,所以应该是安全的,尽圆形装载是关注。

__init__ 模块的 一个包裹 就像成员包本身,因此对象是进口直接从 mymod:

from mymod import foo

from . import foo

如果你喜欢要简洁,然后读取有关 相对于进口.你需要确保,一如既往,得不调用的模块 mymod/__main__.py, 例如,因为这将防止蟒蛇从检测 mymod 作为一个软件包。你可能想看看 distutils.

如果你的运行模块用 python -m mymod 那么代码 __main__.py 将能够从进口的其余部分的模块,而无需增加的模块 sys.path.

模块目录的结构如下:

py/
   __init__.py
   __main__.py

__init__.py

#!/usr/bin/python3
#
# __init__.py
#

__all__ = ['foo']
foo = {'bar': 'baz'}
info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)

__main__.py

#!/usr/bin/python3
#
# __main__.py
#

info = { "package": __package__,
         "name": __name__,
         "locals": [x for x in locals().copy()] }
print(info)
from . import info as pyinfo
print({"pyinfo: ": pyinfo})

执行模块,作为一个脚本用的 -m 标志

$ python -m py

# the printout from the 'print(info)' command in __init__.py
{'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}
# the printout from the 'print(info)' command in __main__.py
{'name': '__main__', 'locals': ['__builtins__', '__name__', '__file__', '__loader__', '__doc__', '__package__'], 'package': 'py'}
# the printout from the 'print(pyinfo)' command in __main__.py
{'pyinfo: ': {'name': 'py', 'locals': ['__all__', '__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', '__doc__'], 'package': None}}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top