Python 3 - 问题导入模块 - 从父目录 - 包含文件描述符
Python 3 - Issue importing module - from Parent Directory - that contains File Descriptor
我无法执行我认为应该从文件的父目录简单导入 python3 模块的操作。我可以从父目录导入模块而不会出现问题 直到 我将文件描述符引入到要导入的文件中。
下面的示例 #1 是 'works fine' 场景,#2 是有问题的场景,我希望得到建议。
#1 - 工作正常
应用目录结构:
├── app
│ └── app.py
├── config.py
文件内容:
# 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'
运行它:
$ pwd
app/
$ python app.py
hello from app main
foo is --> bar
#2 - 不工作/失败
应用目录结构:
├── app
│ └── app.py
├── config.py
└── foo.txt <-- **Introduced new file here**
文件内容:
# 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
运行它:
$ 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'
我在这里做错了什么?请注意,尽管出现“FileNotFoundError”错误消息,foo.txt 确实确实存在于父目录中。
$ cat ../foo.txt
bar
谢谢。
What am I doing wrong here?
您正在使用相对路径。这个:
open("foo.txt")
将在 current working directory 中查找 foo.txt,无论此时它是什么(这意味着它可以是任何东西,你永远不应该对它做任何假设)。
And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.
是的,它存在于父目录中,但不存在于当前目录中。
这里的规范解决方案是使用 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()
现在您可以安全地从任何其他模块调用 config.read_foo()
,无论当前工作目录是什么。
附带说明:在 class
语句块中读取文件可能不是一个好主意 - 并不是说它在 Python 中是非法的,但它确实是一种设计味道......
我无法执行我认为应该从文件的父目录简单导入 python3 模块的操作。我可以从父目录导入模块而不会出现问题 直到 我将文件描述符引入到要导入的文件中。
下面的示例 #1 是 'works fine' 场景,#2 是有问题的场景,我希望得到建议。
#1 - 工作正常
应用目录结构:
├── app
│ └── app.py
├── config.py
文件内容:
# 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'
运行它:
$ pwd
app/
$ python app.py
hello from app main
foo is --> bar
#2 - 不工作/失败
应用目录结构:
├── app
│ └── app.py
├── config.py
└── foo.txt <-- **Introduced new file here**
文件内容:
# 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
运行它:
$ 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'
我在这里做错了什么?请注意,尽管出现“FileNotFoundError”错误消息,foo.txt 确实确实存在于父目录中。
$ cat ../foo.txt
bar
谢谢。
What am I doing wrong here?
您正在使用相对路径。这个:
open("foo.txt")
将在 current working directory 中查找 foo.txt,无论此时它是什么(这意味着它可以是任何东西,你永远不应该对它做任何假设)。
And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.
是的,它存在于父目录中,但不存在于当前目录中。
这里的规范解决方案是使用 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()
现在您可以安全地从任何其他模块调用 config.read_foo()
,无论当前工作目录是什么。
附带说明:在 class
语句块中读取文件可能不是一个好主意 - 并不是说它在 Python 中是非法的,但它确实是一种设计味道......