python - 如何从 __main__.py 访问 __init__.py 中的符号?
问题描述
我有一个模块——我们称之为模块——foo
我想通过调用使其可用python -m foo
。我的程序如下所示:
my_project
├── foo
│ └── __init__.py
└── my_program.py
在__init__.py
我有一些我在调用时运行的代码python -m foo
:
def bar(name):
print(name)
# -- code used to 'run' the module
def main(name):
bar("fritz")
if __name__ == "__main__":
main()
因为我现在有相当多的执行代码__init__.py
(argparse
东西和一些逻辑)我想把它分成一个__main__.py
:
my_project
├── foo
│ ├── __init__.py
│ └── __main__.py
└── my_program.py
尽管这对我来说看起来很简单,但我还没有设法导入其中的东西__init__.py
。__main__.py
我知道 - 如果foo
位于site-packages
或通过PYTHONPATH
我可以访问import foo
..
但是,如果我想直接执行 (例如从某个 IDE)并位于任何位置(即不是 Python 查找包的文件夹) - 有没有办法导入(从同一目录)?__main__.py
foo
foo
__init__.py
我试过import .
了import foo
- 但两种方法都失败了(因为它们当然只是意味着别的)
我能做的——至少解释我的目标——是这样的:
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import foo
有效,但丑陋且有点危险,因为我什至不知道我是否真的foo
从同一目录导入..
解决方案
您可以手动设置模块导入状态,就像使用以下__main__.py
命令执行一样-m
:
# foo/__main__.py
import os
import sys
if __package__ is None and __name__ == "__main__": # executed without -m
# set special attributes as if part of the package
__file__ = os.path.abspath(__file__)
__package__ = os.path.basename(os.path.dirname(__file__))
# replace import path for __main__ with path for package
main_path = os.path.dirname(__file__)
try:
index = sys.path.index(dir_path)
if index != 0 or index != 1:
raise ValueError('expected script directory after current directory or matching it')
except ValueError:
raise RuntimeError('sys.path does not include script directory as expected')
else:
sys.path[index] = main_path
# import regularly
from . import bar
此漏洞作为独立脚本python3 path/to/foo/__main__.py
执行: is并且也不包含包。在这种情况下,搜索路径是,但如果两者相同,它就会被折叠:是 0 或 1。__main__
__package__
None
__name__
<current directory>, <__main__ directory>, ...
index
与内部的所有诡计一样,存在一些违反不变量的瞬态。在模块修补之前不要执行任何导入!
推荐阅读
- reactjs - 在 Go 中从 Back 发送 Cookie,这是一个 api 休息,使用 React JS 发送到前端
- c# - 是否可以修改内存中的内容?
- android - 颤振:ListWheelScrollView 放大镜不起作用
- java - 在基于 Spring Boot 的应用程序中使用 REST API 输入在运行时设置模式名称
- java - 加入两个数据帧,限制一个数据帧的行
- c++ - ESP8266,Twilio 不发送短信
- cmake - MinGW64 下 g++ 的 "-x c++" 标志导致 "stray [...] in program" 错误
- javascript - 按钮功能正确,但是单元测试报错
- github - 如何将彩色文本放入 githubs README.md 或 Index.md 文件
- web-scraping - 获取 YouTube 音乐库上传的列表