模块之间的相对导入

Relative import between modules

我编写了一组我想用于计算的函数,并将它们组织在一些 .py 文件中,比如 functions1.pyfunctions2.py。在同一文件夹中,我还有另一个文件 main.py,然后:

root\ 
- functions1.py
- functions2.py 
- main.py

里面 functions1.py 假设我有以下代码:

import numpy as np

def mycos(x): 
    return np.cos(x)

def mysin(x):
    return np.sin(x)

在里面时 functions2.py:

from .functions1 import mysin, mycos

def mytan(x):
    return mysin(x)/mycos(x)

现在假设 main.py 包含:

import numpy as np
from .functions2 import mytan

angle = np.pi/3
if mytan(angle) == np.tan(angle):
    print('OK')

然后,如果我执行 main.py 我得到以下错误:

Traceback (most recent call last):
  File "functions2.py", line 6, in <module>
    from .functions1 import mysin, mycos
ImportError: attempted relative import with no known parent package

我在使用相对导入时是不是遗漏了什么?

我认为这是因为当你运行你不在项目目录中执行的代码时,尝试在main.py

代码的开头添加这几行
import os # don't add this line if you have already imported os
os.chdir(os.path.dirname(os.path.abspath(__file__)))

让我知道这是否有效,如果无效...您可以分享完整的代码以更好地理解您的问题吗?


编辑
问题应该是文件 functions1.py 和 functions2.py 实际上不是模块,为了解决这个问题,我建议你两个解决方案:

创建文件夹

由于这两个函数文件不作为一个模块,所以创建一个文件夹并将它们放在里面

MAINDIR
– main.py
– functions
–– functions1.py
–– functions2.py

代码是这样

main.py

import numpy as np
from functions.functions2 import mytan

angle = np.pi/3
if mytan(angle) == np.tan(angle):
    print('OK')

functions1.py

import numpy as np

def mycos(x):
    return np.cos(x)

def mysin(x):
    return np.sin(x)

functions2.py

from .functions1 import mysin, mycos

def mytan(x):
    return mysin(x)/mycos(x)

使用__init__.py


MAINDIR
– main.py
– functions
–– __init__.py
–– functions1.py
–– functions2.py

这是代码

init.py

import functions1, functions2

(和第一个解决方案一样的所有其他文件)
请注意,这个解决方案有点长,但这应该是最“正确”的做法

然后呢?

如果您想更好地理解为什么它不起作用,我建议您阅读这篇做得很好的文章:
real python
geeks for geeks

干杯 J.Bloom

os.chdir(os.path.dirname(os.path.abspath(__file__))) 建议 所做的是将工作目录更改为 main.py 的父文件夹。这看起来很混乱,并且可能会以微妙的方式失败(相对路径就是其中之一)。正确的解决方案是使用 -m 从 root 的父目录切换到 运行 main.py。这实际上是运行宁python脚本的推荐方式。所以你应该 运行:

$ python -m root.main # from parent dir of root

那么 module main 是 运行 作为 root 包的一部分(这是你的情况下缺少的父包)

请注意,如果您创建一个(子)包(root.)函数,这仍然有效,如上所示 - 添加一个 __init__.py 应该不需要最新的 py3 仍然添加它是个好主意为了清楚起见。