我知道这个主题有很多问题,但是没有一个问题对我有很大帮助。
我有一个python项目目录,即git_project
(git存储库)。我想要创建一个名为notebooks
的单独目录,在该目录中,我将使用git_project保存所有笔记本以进行分析。我不想将笔记本放在git_project的根目录下。我已经将git_project
和notebooks
目录都保留在保存我所有项目的常规目录中。我有以下结构:
my_projects
│
├── notebooks
│ └── notebook.ipynb
└── git_project
└── config
└── cfg.json
└── source
└── config.py
config.py
的内容:
import json
def get_cfg():
with open('config/cfg.json', 'r') as f:
cfg = json.load(f)
return cfg
notebook.ipynb
的内容:
import sys
import os
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
sys.path.append(module_path)
from git_project.source.config import get_cfg
get_cfg()
现在,当我在notebook.ipynb中运行代码时,出现以下错误:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-7-6796ee7f0100> in <module>
----> 1 get_cfg()
~/Documents/my_projects/git_project/source/config.py in get_cfg()
1 def get_cfg():
----> 2 with open('config/cfg.json', 'r') as f:
3 cfg = json.load(f)
4 return cfg
FileNotFoundError: [Errno 2] No such file or directory: 'config/cfg.json'
但是,如果我将notebook.ipynb
文件移动到git_project的根目录。然后我没有得到这个错误。这只是一个例子。我在git_project的其他模块中有很多类似的问题,而git_project包含已经在生产环境中运行的代码。因此,在这里更改git_project中的任何内容都不可行。
但是正如我所说,我不想将笔记本移动到git_project内,而是希望将它们放在并行目录中以进行分析。如果需要,我可以提供更多信息。
我正在使用Python 3.6+,它甚至不需要再放置 init .py文件来制作目录包。
我应该怎么做才能使其正常工作?任何帮助将不胜感激。
答案 0 :(得分:1)
问题是当您调用open('config/cfg.json', 'r')
时,它打开的路径是相对于python代码启动目录的。在这种情况下,它是您的my_projects/notebook
目录。您可以通过在get_cfg()
内的config.py
中添加以下打印品来看到这一点:
print(os.getcwd()) # this prints out the current working directory
print(__file__) # this prints out the path of this script
如艾哈迈德(Ahmet)所建议的那样,修改../git_project/config/cfg.json
的路径是可以的,但是您的python实现将与笔记本文件夹的位置绑定在一起。如果决定重组笔记本文件夹,它将再次损坏。
一种可能的方法是解析脚本路径:__file__
:
import json
import os
def get_cfg():
script_dirname = os.path.dirname(__file__)
config_path = os.path.join(script_dirname, '..', 'config', 'cfg.json')
with open(config_path, 'r') as f:
cfg = json.load(f)
return cfg
相似的建议:(Reading file using relative path in python project)。这也是python-packaging docs中建议的方法:
已安装的库要使用的文件(例如数据文件) 以支持特定的计算方法)通常应放在 在Python模块目录本身中。 ... 这样,加载这些文件的代码可以轻松指定相对 使用者模块的
__file__
变量的路径。
如果您不想触摸git_project
中的当前文件,则可以在python笔记本中运行更改目录命令以指向正确的位置:
In [1]: %cd ../git_project
每次重新启动笔记本内核时,都需要调用该行一次。您也可以在笔记本中验证当前工作目录:
In [2]: %ls
答案 1 :(得分:0)
作为评论中讨论的后续内容...
即使采用相对路径的方法行得通,通常还是最好使用更具可扩展性的方法-将环境变量与项目根目录一起使用。
在这种情况下,您的笔记本电脑真正独立于项目,并且可以根据需要使用任意数量的笔记本电脑。
这是有关如何在Jupiter中使用ENV
变量的绝佳explanation。
我更喜欢使用dotenv
方法。
在您的笔记本文件夹中创建.env
。在您的项目路径中添加变量:
MY_PROJECT_ROOT=/usr/any/path/you/want
然后在笔记本中
import os
from dotenv import load_dotenv
load_dotenv() # this line loads .env file
然后输入您的代码
module_path = os.path.abspath(os.getenv('MY_PROJECT_ROOT'))
if module_path not in sys.path:
sys.path.append(module_path)