简体   繁体   English

Python 3 - 问题导入模块 - 从父目录 - 包含文件描述符

[英]Python 3 - Issue importing module - from Parent Directory - that contains File Descriptor

I am unable to do what I believe should be a simple import of a python3 module from a file's parent directory.我无法执行我认为应该是从文件的父目录简单导入 python3 模块的操作。 I can get the module import to work from a parent directory without issue until I introduce a file descriptor into the file that is to be imported.我可以让模块导入从父目录正常工作,直到我将文件描述符引入要导入的文件。

Example # 1 below is a 'works fine' scenario and # 2 is the problematic scenario that I'm hoping for suggestions on.下面的示例#1 是一个“工作正常”的场景,#2 是我希望得到建议的有问题的场景。

#1 - Works fine #1 - 工作正常

App Directory structure:应用目录结构:

├── app
│   └── app.py
├── config.py

File contents:文件内容:

# app.py
import sys
sys.path.insert(0, '../')
from config import Config as conf

foo = conf.foo

if __name__ == '__main__':
    print('hello from app main')
    print(f'foo is --> {foo}')


#config.py
class Config():
    foo = 'bar'

Run it:运行:

$ pwd
app/
$ python app.py
hello from app main
foo is --> bar

#2 - Does not work / Fails #2 - 不工作/失败

App Directory structure:应用目录结构:

├── app
│   └── app.py
├── config.py
└── foo.txt <-- **Introduced new file here**

File contents:文件内容:

# app.py
import sys
sys.path.insert(0, '../')
from config import Config as conf

foo = conf.foo

if __name__ == '__main__':
    print('hello from app main')
    print(f'foo is --> {foo}')

# config.py
class Config():
    with open('foo.txt', 'rt') as f:
        foo = f.readline().rstrip()   
    
# foo.txt
bar

Run it:运行:

$ pwd
app/

$ python app.py
Traceback (most recent call last):
  File "app.py", line 3, in <module>
    from config import Config as conf
  File "../config.py", line 1, in <module>
    class Config():
  File "../config.py", line 2, in Config
    with open('foo.txt', 'rt') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'foo.txt'

What am I doing wrong here?我在这里做错了什么? And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.请注意,尽管出现“FileNotFoundError”错误消息,但实际上 foo.txt确实存在于父目录中。

$ cat ../foo.txt
bar

Thanks.谢谢。

What am I doing wrong here?我在这里做错了什么?

You are using a relative path.您正在使用相对路径。 This:这个:

open("foo.txt")

will lookup foo.txt in the current working directory , whatever it is at this exact moment (which means that it can be just anything and that you should NEVER assume anything about it).将在当前工作目录中查找 foo.txt ,无论此时它是什么(这意味着它可以是任何东西,你永远不应该对它做任何假设)。

And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.请注意,尽管出现“FileNotFoundError”错误消息,但实际上 foo.txt 确实存在于父目录中。

Yes, it exists in the parent directory, but not in the current directory.是的,它存在于父目录中,但不存在于当前目录中。

The canonical solution here is to rebuild the proper path using os.path functions and the __file__ magic variable:这里的规范解决方案是使用os.path函数和__file__魔术变量重建正确的路径:

# config.py
import os

def read_foo():
    # build the full path to the current file
    here = os.path.abspath(__file__)
    # extract the directory path
    dirpath = os.path.dirname(here)
    # foo.txt is supposed to be in the same directory:
    foopath = os.path.join(dirpath, "foo.txt")
    with open(foopath) as f:
        return f.readline().rstrip()

Now you can safely call config.read_foo() from any other module, whatever the current working directory is.现在您可以安全地从任何其他模块调用config.read_foo() ,无论当前工作目录是什么。

As a side note: reading a file in a class statement block is possibly not a great idea - not that it's illegal in Python but it's really a design smell...附带说明:在class语句块中读取文件可能不是一个好主意 - 并不是说​​它在 Python 中是非法的,但它确实是一种设计味道......

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

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