导入模块,名称与python 3中的内置模块相同

时间:2019-02-09 00:31:17

标签: python-3.x import python-import

我遇到了类似的问题,可以简化为以下问题:

例如,我的文件结构如下:

----folder
    ---- main.py
    ---- math.py

我在math.py中定义了一个函数,我想在math.py中导入此main.py

下面是math.py中的代码

# math.py
def f(x) :
    return x**3

如果我在main.py中按如下方式编写代码

# main.py
import math

def main() :
    print(math.f(3))

if __name__ == "__main__":
    main()

然后返回AttributeError: module 'math' has no attribute 'f'

如果我在main.py中按如下方式编写代码

# main.py
from . import math

def main() :
    print(math.f(3))

if __name__ == "__main__":
    main()

然后返回ImportError: cannot import name 'math' from '__main__' (main.py)

我的问题:

  1. 如果我仅 要在路径math.py中导入与内置模块同名的模块folder,该怎么办?< / p>

  2. 如果我要在main.py和内置math.f(x)中定义的两者 math.py中使用我该怎么办?

PS:我遇到类似的问题,因为十年前有人编写了很长的代码。那时还没有内置这样名称的模块(实际上,它不是math.acos(x)模块。我只是通过上述问题简化了问题)。并且该模块的功能已在许多地方使用。因此,几乎不可能更改模块的名称,因为如果需要,则需要仔细更改所有站点math

2 个答案:

答案 0 :(得分:1)

以内置模块命名模块是非常不好的做法。我建议为您的math.py命名其他名称。

话虽如此,您可以使用带有imp的路径将其导入:

import imp
math = imp.load_source('math', './math.py')

答案 1 :(得分:0)

钻入一个兔子洞,但是我们开始。作为免责声明,就像杰克(Jack)所说的那样,在内建函数之后命名模块是非常不好的做法,这可以使用他建议的imp更容易地实现。

您遇到问题的原因来自几件事的相互作用。键入

import math

您的python所做的是查看sys.path。它将在sys.path中的所有位置中检入名为math的模块,并导入找到的第一个模块。在您的情况下,它将首先找到您的本地数学模块。导入完成后,将其添加到sys.modules中,但我们将继续介绍。

由于您要同时使用两者,因此可以先导入本地数学。我建议将其导入为其他名称以使其分开。

from . import math as local_math

在那之后,我们需要弄乱sys.path来找到内置数学

sys.path = sys.path[::-1]

这将颠倒sys.path的顺序,这意味着它将首先在您的本地目录中查找,而不是最后一个。

现在您可能认为这已经足够,但是如果您尝试在此处导入数学,则python将在sys.modules中看到它,而无需再尝试再次导入,因此首先

del sys.modules['math']

然后我们可以导入默认的数学模块

import math

最后清理我们的sys.path

sys.path = sys.path[::-1]

现在我们可以访问所需的一切

>>>math.cos(10)
-0.8390715290764524
>>>local_math.f(10)
1000