在python项目中使用相对路径读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40416072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading file using relative path in python project
提问by pbreach
Say I have a python project that is structured as follows:
假设我有一个结构如下的 python 项目:
project
/data
test.csv
/package
__init__.py
module.py
main.py
__init__.py
:
__init__.py
:
from .module import test
module.py
:
module.py
:
import csv
with open("..data/test.csv") as f:
test = [line for line in csv.reader(f)]
main.py
:
main.py
:
import package
print(package.test)
When I run main.py
I get the following error:
当我运行时main.py
,出现以下错误:
C:\Users\Patrick\Desktop\project>python main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
import package
File "C:\Users\Patrick\Desktop\project\package\__init__.py", line 1, in <module>
from .module import test
File "C:\Users\Patrick\Desktop\project\package\module.py", line 3, in <module>
with open("../data/test.csv") as f:
FileNotFoundError: [Errno 2] No such file or directory: '../data/test.csv'
However, if I run module.py
from the package
directory I get no errors. So it seems that the relative path used in open(...)
is only relative to where the originating file is being run from (i.e __name__ == "__main__"
)? I don't want to use absolute paths. What are some ways to deal with this?
但是,如果我module.py
从package
目录运行,则不会出现任何错误。因此,似乎使用的相对路径open(...)
仅与原始文件的运行位置有关(即__name__ == "__main__"
)?我不想使用绝对路径。有什么方法可以解决这个问题?
回答by spectras
Relative paths are relative to current working directory. If you do not your want your path to be, it must be absolute.
相对路径是相对于当前工作目录的。如果您不希望自己的路径成为,那么它必须是绝对的。
But there is an often used trick to build an absolute path from current script: use its __file__
special attribute:
但是有一个常用的技巧可以从当前脚本构建绝对路径:使用它的__file__
特殊属性:
import csv
import os.path
my_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(my_path, "../data/test.csv")
with open(path) as f:
test = list(csv.reader(f))
Note, from python 3.4, __file__
is always absolute for imported modules and you can drop the os.path.abspath
part in this example.
请注意,从 python 3.4 开始,__file__
对于导入的模块始终是绝对的,您可以os.path.abspath
在此示例中删除该部分。
Better yet with python 3.4+, use the Path module as jpyams suggested in the comment below:
使用 python 3.4+ 更好,使用 Path 模块作为 jpyams 在下面的评论中建议:
from pathlib import Path
path = Path(__file__).parent / "../data/test.csv"
with path.open() as f:
test = list(csv.reader(f))
回答by aksh1618
For Python 3.4+:
对于 Python 3.4+:
import csv
from pathlib import Path
base_path = Path(__file__).parent
file_path = (base_path / "../data/test.csv").resolve()
with open(file_path) as f:
test = [line for line in csv.reader(f)]
回答by kaspiotr
My Python version is Python 3.5.2and the solution proposed in the accepted answer didn't work for me. I've still were given an error
我的 Python 版本是Python 3.5.2,接受的答案中提出的解决方案对我不起作用。我仍然收到一个错误
FileNotFoundError: [Errno 2] No such file or directory
when I was running my_script.py
from the terminal. Although it worked fine when I run it through Run/Debug Configurations from PyCharm IDE (PyCharm 2018.3.2 (Community Edition)).
当我my_script.py
从终端运行时。尽管当我通过 PyCharm IDE(PyCharm 2018.3.2(社区版))的运行/调试配置运行它时它运行良好。
Solution:
解决方案:
instead of using:
而不是使用:
my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path
as suggested in the accepted answer, I used:
正如接受的答案中所建议的那样,我使用了:
my_path = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) + some_rel_dir_path
Explanation:
Changing os.path.dirname(__file__)
to os.path.dirname(os.path.abspath(__file__))
solves the following problem:
说明:更改os.path.dirname(__file__)
为os.path.dirname(os.path.abspath(__file__))
解决以下问题:
When we run our script like that: python3 my_script.py
the __file__
variable has a just a string value of "my_script.py" without path leading to that particular script. That is why method dirname(__file__)
returns an empty string "". That is also the reson why my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path
is actually the same thing as my_path = some_rel_dir_path
. Consequently FileNotFoundError: [Errno 2] No such file or directory
is given when trying to use open
method because there is no directory like "some_rel_dir_path".
当我们运行脚本那样:python3 my_script.py
该__file__
变量具有“my_script.py”没有通往那个特定的脚本只是一个字符串值。这就是方法dirname(__file__)
返回空字符串“”的原因。这也是为什么my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path
实际上与my_path = some_rel_dir_path
. 因此FileNotFoundError: [Errno 2] No such file or directory
在尝试使用open
方法时给出,因为没有像“some_rel_dir_path”这样的目录。
Running script from PyCharm IDE Running/Debug Configurations worked because it runs a command python3 /full/path/to/my_script.py
(where "/full/path/to" is specified by us in "Working directory" variable in Run/Debug Configurations) instead of justpython3 my_script.py
like it is done when we run it from the terminal.
从 PyCharm IDE 运行/调试配置运行脚本之所以有效,是因为它运行一个命令python3 /full/path/to/my_script.py
(其中“/full/path/to”是我们在运行/调试配置的“工作目录”变量中指定的),而不是python3 my_script.py
像我们那样从终端运行它。
Hope that will be useful.
希望这将是有用的。