模块之间的相对导入 创建文件夹使用__init __py 然后呢?

问题描述

我已经编写了一组要用于计算的函数,并将它们组织在某个.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__)))建议above所做的工作是将工作目录更改为main.py的父文件夹。这看起来很杂乱,并且可能以微妙的方式失败(相对路径是其中之一)。正确的解决方案是从根目录的父目录使用-m开关运行main.py。实际上,这是运行python脚本的推荐方法。所以你应该运行:

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

然后 module 主程序作为root程序包(您的情况下缺少的父程序包)的一部分运行

请注意,如果您按照上面的建议创建(子)程序包(root。)函数,此方法仍然可以使用-最新的py3无需添加__init__.py,为清楚起见,还是添加它是一个好主意。 / p>