题
我试图访问模块的数据,从其内部 __main__.py
.
结构如下:
mymod/
__init__.py
__main__.py
现在,如果我获得一个变量 __init__.py
是这样的:
__all__ = ['foo']
foo = {'bar': 'baz'}
我如何可以访问 foo
从 __main__.py
?
解决方案
你需要或有软件包已经在 sys.path
, 添加的含有目录 mymod
要 sys.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__.py
和 python -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__
, ,所以应该是安全的,尽圆形装载是关注。
如果你的运行模块用 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}}