使用 src 子文件夹时从配置文件导入
import from config file when using src subfolder
我想在 /src/cool_api.py
中使用我的 get_data()
:
- a)
cool_api.py
的主块
- b)
main.py
的主块
get_data()
需要从 config/api_config.yaml 导入 API 密钥,这会导致在尝试 b) 时出现 FileNotFoundError。 对于像这样从 src
导入的内容,是否有默认(非 hacky)解决方案?
我有以下文件结构:
|─ config
│ ├─ api_config.yaml
|─ src # marked as Sources Root folder in Pycharm
│ ├─ cool_api.py
│ └─ ...
├─ tests
│ └─ test_cool_api.py
└─ main.py
我的代码:
# cool_api.py
def get_data():
import yaml
import requests
with open("../config/api_config.yaml") as f:
config = yaml.load(f, Loader=yaml.SafeLoader)
return f"cool_api.org?key={config['api_key']}"
if __name__ == "__main__":
print(get_data())
a) 有效。
# main.py
from cool_api.py import get_data
if __name__ == "__main__":
print(get_data())
b) 结果为 FileNotFoundError
。没有这样的文件或目录:'../config/api_config.yaml'
如何修复我的导入语句?
可选:是否有 Pycharm 用户的快捷方式?
能否在配置文件夹中添加一个空的 __init__.py
文件
这与导入无关,因为您没有导入 YAML 文件,而是将其作为文件打开,并且您使用的是相对于 Python过程。您收到 FileNotFound 错误,因为工作目录是 main.py
所在的目录,从那里向上一个目录,不会有 config/
目录。
如果您知道配置文件将始终与 cool_api.py
相关,请使用 __file__
(这是指向模块绝对路径的内置函数),并从中计算路径那里。
import os
config_dir = os.path.join(os.path.dirname(__file__), '..', 'config')
config_file = os.path.join(config_dir, 'config.yaml')
with open(config_file):
...
关于导入,我想说你的文件结构不是最理想的;您现在可以在 main.py
中 import cool_api
的唯一原因是 PyCharm 修复了您的 Python 源路径以包含 src/
;如果您尝试在控制台中 python main.py
,那是行不通的。
我建议将代码结构化为项目根目录中的包:
cool_api/
__init__.py # likely mostly empty
__main__.py # main entry point
config.py # contains `get_data` and others
带有 __main__
模块的包可以使用(例如)python -m cool_api
或 运行 配置 -> 目标类型:“模块名称”(而不是“脚本路径” ) PyCharm.
中的选项
运行 该选项还有一个额外的好处,即 Python 本身会修复您的模块路径,因此 import cool_api.config
始终有效,并且 from .config import get_data
在包内有效,等等。
我想在 /src/cool_api.py
中使用我的 get_data()
:
- a)
cool_api.py
的主块 - b)
main.py
的主块
get_data()
需要从 config/api_config.yaml 导入 API 密钥,这会导致在尝试 b) 时出现 FileNotFoundError。 对于像这样从 src
导入的内容,是否有默认(非 hacky)解决方案?
我有以下文件结构:
|─ config
│ ├─ api_config.yaml
|─ src # marked as Sources Root folder in Pycharm
│ ├─ cool_api.py
│ └─ ...
├─ tests
│ └─ test_cool_api.py
└─ main.py
我的代码:
# cool_api.py
def get_data():
import yaml
import requests
with open("../config/api_config.yaml") as f:
config = yaml.load(f, Loader=yaml.SafeLoader)
return f"cool_api.org?key={config['api_key']}"
if __name__ == "__main__":
print(get_data())
a) 有效。
# main.py
from cool_api.py import get_data
if __name__ == "__main__":
print(get_data())
b) 结果为 FileNotFoundError
。没有这样的文件或目录:'../config/api_config.yaml'
如何修复我的导入语句?
可选:是否有 Pycharm 用户的快捷方式?
能否在配置文件夹中添加一个空的 __init__.py
文件
这与导入无关,因为您没有导入 YAML 文件,而是将其作为文件打开,并且您使用的是相对于 Python过程。您收到 FileNotFound 错误,因为工作目录是 main.py
所在的目录,从那里向上一个目录,不会有 config/
目录。
如果您知道配置文件将始终与 cool_api.py
相关,请使用 __file__
(这是指向模块绝对路径的内置函数),并从中计算路径那里。
import os
config_dir = os.path.join(os.path.dirname(__file__), '..', 'config')
config_file = os.path.join(config_dir, 'config.yaml')
with open(config_file):
...
关于导入,我想说你的文件结构不是最理想的;您现在可以在 main.py
中 import cool_api
的唯一原因是 PyCharm 修复了您的 Python 源路径以包含 src/
;如果您尝试在控制台中 python main.py
,那是行不通的。
我建议将代码结构化为项目根目录中的包:
cool_api/
__init__.py # likely mostly empty
__main__.py # main entry point
config.py # contains `get_data` and others
带有 __main__
模块的包可以使用(例如)python -m cool_api
或 运行 配置 -> 目标类型:“模块名称”(而不是“脚本路径” ) PyCharm.
运行 该选项还有一个额外的好处,即 Python 本身会修复您的模块路径,因此 import cool_api.config
始终有效,并且 from .config import get_data
在包内有效,等等。