python-在__main__.py中使用模块自己的对象

我正在尝试从其__main__.py内部访问模块的数据。

结构如下:

mymod/
    __init__.py
    __main__.py

现在,如果我在foo中公开这样的变量:

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

如何从__main__.py访问foo

sharvey asked 2020-08-12T07:05:50Z
5个解决方案
23 votes

您需要已经在-m中拥有该软件包,将包含__main__.py的目录添加到__main__.py中的sys.path,或者使用-m开关。

要将-m添加到路径中,如下所示(在__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

使用300778997594242464512开关将需要:

python -m mymod

请参阅此答案以获取更多讨论。

pdemb answered 2020-08-12T07:06:11Z
4 votes

我最常遇到的问题是我经常想将main.py文件作为脚本运行以测试功能,但是在加载程序包时不应运行这些功能。 对于__init__.py__init__.py之间的不同执行路径,有一个有用的解决方法。

  • main.py执行__init__.py__init__.py未加载。
  • main.py像普通脚本一样简单地执行脚本__init__.py


问题

如果我们希望main.py包含一个__init__.py子句,该子句使用__init__.py中的内容。我们无法导入__init__,因为它将始终从解释程序的路径中导入main.py。 (除非…我们求助于绝对路径导入黑客,这可能会导致很多其他混乱)。


解决方案和解决方案:)

为模块的main.py使用两个脚本文件:

<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__'

在我们从__init__.py运行的情况下,main.py中的导入可能并不理想,因为我们已经将它们重新加载到另一个模块的本地范围中,尽管已经在__init__.py中进行了加载,但是显式加载应避免循环加载。 如果确实将整个__init__模块再次加载到main.py中,则不会以__main__的形式加载它,因此就循环加载而言应该是安全的。

Nisan.H answered 2020-08-12T07:07:08Z
2 votes

包的mymod/__main__.py模块的作用类似于包本身的成员,因此直接从mymod导入对象:

from mymod import foo

要么

from . import foo

如果您想简洁,请阅读有关相对导入的信息。 与往常一样,您需要确保不调用例如mymod/__main__.py的模块,因为这将阻止Python将mymod检测为包。 您可能希望研究distutils

Josh Lee answered 2020-08-12T07:07:40Z
1 votes

如果使用python -m mymod运行模块,则__main__.py中的代码将能够从模块的其余部分导入,而不必将模块添加到sys.path

glyphobet answered 2020-08-12T07:08:00Z
-2 votes

模块目录结构如下:

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})

使用$ python -m py标志将模块作为脚本执行

$ 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}}
cogsmos answered 2020-08-12T07:08:33Z
translate from https://stackoverflow.com:/questions/3411293/using-modules-own-objects-in-main-py