第三个包模块中的Python本地模块名称隐藏标准库

第三个包模块中的Python本地模块名称隐藏标准库,python,python-3.x,Python,Python 3.x,我正在使用,发现主模块中存在平台模块时出现导入错误: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/duranda/.local/lib/python3.6/site-packages/usb1/__init__.py", line 61, in <module> from . import libusb1 File "/

我正在使用,发现主模块中存在平台模块时出现导入错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/duranda/.local/lib/python3.6/site-packages/usb1/__init__.py", line 61, in <module>
    from . import libusb1
  File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 199, in <module>
    libusb = _loadLibrary()
  File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 161, in _loadLibrary
    system = platform.system()
AttributeError: module 'platform' has no attribute 'system'
通过从包含platform.py或platform/\uuu init\uuu.py的目录启动Python解释器,然后使用import usb1导入usb1,可以很容易地复制这一点


本地模块与另一个模块(在本例中为来自第三方模块的标准库的平台模块)之间的阴影是如何可能的?就我所知,libusb1并没有对globals做任何疯狂的事情。

在模块中添加第一行:

import sys
print("\n".join(sys.path))

import platform
print("platform file is", platform.__file__)
这可能会表明python路径尝试首先导入本地模块,然后才导入系统模块

换句话说。不要使用名称与系统或第三方模块名称冲突的本地模块

更多解释:

如果多个模块导入具有相同名称的模块,那么python只导入该模块一次

只有第一次导入才能导入模块 第二次导入将只指向已经导入的模块,它将在sys.modules中找到该模块

因此,可以将模块名视为指向python代码的唯一指针。 尝试打印sys.modules这是一个dict,它将显示到目前为止导入的模块

因此,导入语句位于您的文件还是第三方文件中并不重要

导入平台将仅指向一个模块。正在选择/找到的是python路径中首先出现的


因此,自编模块的名称不应与现有模块的名称冲突。

添加为模块的第一行:

import sys
print("\n".join(sys.path))

import platform
print("platform file is", platform.__file__)
这可能会表明python路径尝试首先导入本地模块,然后才导入系统模块

换句话说。不要使用名称与系统或第三方模块名称冲突的本地模块

更多解释:

如果多个模块导入具有相同名称的模块,那么python只导入该模块一次

只有第一次导入才能导入模块 第二次导入将只指向已经导入的模块,它将在sys.modules中找到该模块

因此,可以将模块名视为指向python代码的唯一指针。 尝试打印sys.modules这是一个dict,它将显示到目前为止导入的模块

因此,导入语句位于您的文件还是第三方文件中并不重要

导入平台将仅指向一个模块。正在选择/找到的是python路径中首先出现的

因此,自编模块的名称不应与现有模块冲突。

因为模块平台位于您的工作目录中,Python解释器将在开始时将当前工作目录插入sys.path。您可以打印sys.path以进行检查

因此,Python解释器使用基于sys.path查找模块时找到的第一个模块,它是您自己的模块,而不是标准库中的模块

解决方法是将当前工作目录移动到结束位置;请注意,将其放在文件的顶部,然后导入模块

import sys
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
更多评论:

回复@gelonida:假设我们真的想使用这两个模块, 我们可以先导入一个,给它一个别名,然后修改它 sys.path以导入另一个

由于模块平台位于您的工作目录中,Python解释器会在开始时将当前工作目录插入sys.path。您可以打印sys.path以进行检查

因此,Python解释器使用基于sys.path查找模块时找到的第一个模块,它是您自己的模块,而不是标准库中的模块

解决方法是将当前工作目录移动到结束位置;请注意,将其放在文件的顶部,然后导入模块

import sys
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
更多评论:

回复@gelonida:假设我们真的想使用这两个模块, 我们可以先导入一个,给它一个别名,然后修改它 sys.path以导入另一个


如何导入这些模块?libusb1使用导入平台,而我的模块导入usb1。没有与的相对导入。注释。您是如何导入这些模块的?libusb1使用导入平台,而我的模块导入usb1。没有与的相对导入。虽然我知道在我的模块中使用import platform将导入本地模块,但为什么它也使用来自导入的第三方模块/库的本地模块for platform呢?请看python路径的输出。这将显示python搜索模块的位置和顺序。不管import语句是在第三方模块中还是在您自己的模块中,这都无关紧要。绝对导入的搜索顺序始终相同。虽然您可能会更改python路径的顺序,但我认为最好重命名您的模块。我的答案有点增强。Whil
e我知道在我的模块中使用import platform将导入本地模块,为什么它也使用来自导入的第三方模块/库的本地模块for platform?请看python路径的输出。这将显示python搜索模块的位置和顺序。不管import语句是在第三方模块中还是在您自己的模块中,这都无关紧要。绝对导入的搜索顺序始终相同。虽然您可能会更改python路径的顺序,但我认为最好重命名您的模块。我的答案稍微增强了一点。同意,这应该可以解决问题。但正如我提到的。在我看来,最好重命名您自己的模块,这样,即使路径没有更改,也不会发生模块名称冲突尽管我忘了提到,请求将在那时起作用,但是如果您的其余代码尝试导入您自己的platform.py,它将失败,因为在这种情况下,系统的平台模块已经导入。同意,这应该可以解决问题。但正如我提到的。在我看来,最好重命名您自己的模块,这样,即使路径没有更改,模块名称冲突也不会发生。尽管我忘了提到,请求将在那时起作用,但是如果您的其余代码尝试导入您自己的platform.py,它将失败,因为在这种情况下,系统的平台模块已经导入。