1

我编写了一组我想用于计算的函数,并将它们组织在一些 .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

我在使用相对导入时错过了什么吗?

4

2 回答 2

2

我认为这是因为当您运行不在项目目录中执行的代码时,请尝试在 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

代码是这样的

主文件

import numpy as np
from functions.functions2 import mytan

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

函数1.py

import numpy as np

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

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

函数2.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

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

进而?

如果您想更好地理解为什么它不起作用,我建议您阅读这篇出色的文章:
真正的 Python
极客为极客

干杯 J.Bloom
于 2020-10-26T11:26:33.833 回答
1

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

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

然后模块main 作为root包的一部分运行(这是您的情况下缺少的父包)

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

于 2020-10-27T14:30:30.310 回答