简体   繁体   English

获取Python中导入模块的文件相对路径

[英]Get Path of File Relative Path of File that Imported Module in Python

I have this code in my_program.py :我在my_program.py中有这段代码:

from my_module import do_stuff_with_file

do_stuff_with_file("hi.txt")

And this is my_module.py :这是my_module.py

def do_stuff_with_file(fileName):
    print(fileName)
    # do stuff with the file

A file not found error arises when my_module.py is not in the same directory as my_program.py .my_module.pymy_program.py不在同一目录中时,会出现文件未找到错误。 This problem was solved using this code ( my_module.py ).使用此代码 ( my_module.py ) 解决了这个问题。

def do_stuff_with_file(fileName):
    fileName = os.path.join(os.path.dirname(sys.modules['__main__'].__file__), fileName)
    print(fileName)
    # do stuff with file

The issue arises when my_program.py is imported by a file in a different directory.my_program.py由不同目录中的文件导入时,就会出现此问题。

How can I fix this?我怎样才能解决这个问题?

Given the following file hierarchy:给定以下文件层次结构:

stack_overflow/
├─ q67993523/
   ├─ my_module/
   │  ├─ __init__.py
   ├─ 67993523.py
   ├─ hi.txt

With the following file content:具有以下文件内容:

# 67993523.py
from my_module import do_stuff_with_file

do_stuff_with_file("hi.txt")
# my_module/__init__.py
def do_stuff_with_file(filename):
    print(f"{filename!s} content is :")
    with open(filename, "rt") as file:
        print(file.read())

and the file hi.txt :和文件hi.txt

Hello !

When I run C:\path\to\python.exe C:/stack_overflow/q67993523/67993523.py (with the path to q67993523 included in my PYTHONPATH ), with my current directory being q67993523/ , I get: When I run C:\path\to\python.exe C:/stack_overflow/q67993523/67993523.py (with the path to q67993523 included in my PYTHONPATH ), with my current directory being q67993523/ , I get:

hi.txt content is :
Hello !

But if I change my current dir to q67993523/my_module/ and execute the exact same command, I get:但是,如果我将当前目录更改为q67993523/my_module/并执行完全相同的命令,我会得到:

hi.txt content is :
Traceback:
[...]
FileNotFoundError: [Errno 2] No such file or directory: 'hi.txt'

because relative to the current working directory q67993523/my_module/ there is no file hi.txt , the file would be ../hi.txt .因为相对于当前工作目录q67993523/my_module/没有文件hi.txt ,该文件将是../hi.txt

I think what you are doing is an instance of the XY problem .我认为您正在做的是XY 问题的一个实例。

What you are trying to achieve is to find a file given its name but not the location.您想要实现的是找到一个给定名称而不是位置的文件。 It is very difficult to do, prone to error, and would include lots of hacks to work.这很难做到,容易出错,并且需要大量的黑客攻击
I don't think it is actually what you want to do.我不认为这实际上是你想要做的。 What you want to do, I presume, is not to search for files but just to use them.我想你想做的不是搜索文件,而是使用它们。 So you should not lose the precious information of their location.所以你不应该丢失他们位置的宝贵信息。

For example, in your main script (mine is 67993523.py ), you know that the file is right there, in the same directory.例如,在您的主脚本(我的是67993523.py )中,您知道该文件就在同一目录中。 But if you just send hi.txt , because the function don't know the file location of the code that called her, it does not know where to search for the file.但是如果你只是发送hi.txt ,因为 function 不知道调用她的代码的文件位置,它不知道在哪里搜索文件。
Instead, give the complete file location , namely the absolute path.相反,给出完整的文件位置,即绝对路径。

If I change my main script to:如果我将主脚本更改为:

# 67993523.py
from pathlib import Path

from my_module import do_stuff_with_file

the_directory_of_this_pyfile = Path(__file__).parent
do_stuff_with_file((the_directory_of_this_pyfile / "hi.txt").absolute())

And run it with my current directory being q67993523/ , I get:并在当前目录为q67993523/的情况下运行它,我得到:

C:\stack_overflow\q67993523\hi.txt content is :
Hello !

And when I change my current directory to q67993523/my_module/ , I get the same thing:当我将当前目录更改为q67993523/my_module/时,我得到了同样的结果:

C:\stack_overflow\q67993523\hi.txt content is :
Hello !

The difference is that in your script, the hi.txt filename assumes that your current working directory is q67993523/ .不同之处在于,在您的脚本中, hi.txt文件名假定您当前的工作目录是q67993523/ If you have a different current working directory (because Pytest, because running the script for anywhere you want, ... see the comment from @tdelaney) then there is no ./hi.txt file, so it will fail.如果您有不同的当前工作目录(因为 Pytest,因为在您想要的任何地方运行脚本,......请参阅@tdelaney 的评论)然后没有./hi.txt文件,所以它会失败。

I encourage you to learn on the topic of current working directory and how to express the current Python file directory .我鼓励您学习有关当前工作目录以及如何表示当前 Python 文件目录的主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM