python - 在 Python 3.x 中导入时的问题
问题描述
我的问题可以总结如下。
我有以下文件结构:
<path>/
- a.py
<path>/subdir/
- b.py
- c.py
关系是 a 导入 b 和 b 导入 c (a->b->c)。
更准确地说,每个文件的内容如下:
- c.py
def foo():
print("Hello World!")
- b.py
import c
def fie():
c.foo()
print("Second Hello World!")
if __name__=="__main__":
fie()
- 一个.py
from subdir import b
b.fie()
我想要的是调用 a.py 将打印这些字符串,即:
$ python3 a.py
Hello World!
Second Hello World!
$
并从 /subdir 调用 b.py 将打印相同的内容:
$ cd subdir
$ python3 b.py
Hello World!
Second Hello World!
$
相反,如果我调用 a.py<path>
我有这个:
$ python3 a.py
Traceback (most recent call last):
File "a.py", line 1, in <module>
from subdir import b
File "<path>/subdir/b.py", line 1, in <module>
import c
ModuleNotFoundError: No module named 'c'
$
相反,如果我从<path>/subdir
我有预期的行为调用 b.py:
$ cd subdir
$ python3 b.py
Hello World!
Second Hello World!
$
如果我通过以下方式更改 b.py :
- b.py
from subdir import c
def fie():
c.foo()
print("Second Hello World!")
if __name__=="__main__":
fie()
a.py 的调用按预期工作,但这次是 b.py 的调用,它给出ModuleNotFoundError
:
$ cd subdir
$ python3 b.py
Traceback (most recent call last):
File "b.py", line 1, in <module>
from subdir import c
ModuleNotFoundError: No module named 'subdir'
$
奇怪的是,即使这个调用 from<path>
给出了同样的错误:
$ python3 subdir/b.py
Traceback (most recent call last):
File "b.py", line 1, in <module>
from subdir import c
ModuleNotFoundError: No module named 'subdir'
$
如果我在 b.py 中替换以下字符串:
from subdir import c
在
from . import c
我和上次测试的效果完全一样。
在实际情况下,b 和 c 都是子目录中自包含库的一部分,该库既可以直接使用(使用if __name__
技巧),也可以从其他任何地方导入以使用它们的功能。目前无法将所述库安装在文件系统的固定空间中(或者至少我不应该依赖它)。
我在使用 Python 2.6 时从未遇到过这样的问题,而且我最近正在迁移到 Python 3.x。阅读 python 3.x 导入指南很有帮助,但我没有找到任何有用的信息来解决这个应该非常基本的案例(这就是为什么我认为我在那里省略了一些微不足道的东西)。
您能否建议一种方法来更改任何 [a,b,c].py 文件以涵盖此用例?
解决方案
以下对我有用(至少在 Windows 下)。
addpath
通过调用将您希望应用程序访问的目录(作为字符串)或目录(作为字符串列表)作为参数来启动您的主程序:
def addpath(dirs):
import sys,os
my_path = '/'.join(os.path.abspath(sys.argv[0]).replace('\\','/').split('/')[:-1])+'/'
if type(dirs) is str:
sys.path.append(my_path+dirs)
elif type(dirs) is list:
for dir in dirs:
sys.path.append(my_path+dir)
################################################################################
addpath('subdir') #or addpath(['subdir1',...])
from subdir import b
b.fie()
推荐阅读
- javascript - 如何在运行下一个方法之前从数组中删除一个项目?
- ios - 在 iOS 版 Chrome 中下载 Apple Pass 时出错
- python - 从 numpy.timedelta64 转换为时间间隔
- rust - 有哪些选项可用于管理错误“无法借用 `*self` 作为可变/不可变”?
- vue.js - 如何修复:this.setDynamic 不是函数
- javascript - 如何使 onkeyup 仅成为字母键?
- ios - 将 JSON 数据与单元格一起使用
- graphql - 使用 apollo graphql 客户端记录请求时间的正确方法是什么?
- reactjs - 在由上下文 API 管理的状态旁边维护类中的状态是否有意义?
- json - 尽管有足够的内存用于执行和缓存,为什么 spark 无法读取大型 JSON 文本文件?