AttributeError:模块“X”在 Python 中没有属性“Y”

AttributeError: 模块 ‘X’ 在 Python 中没有属性 ‘Y’

AttributeError: module ‘X’ has no attribute ‘Y’ in Python

Python“AttributeError: module has no attribute”的出现有多种原因:

  1. 文件之间存在循环依赖,例如文件A导入文件B
    ,反之亦然。
  2. 具有与导入模块同名的本地模块。
  3. 导入语句不正确。(用于print(dir(your_module))查看您导入的内容)
  4. 试图访问模块上不存在的属性。

attributeerror 模块没有属性

不要用第三方模块的名字命名本地文件

这是一个示例,说明当导入的模块被具有相同名称的本地文件隐藏时如何导致错误。

main.py这是一个使用模块命名的文件requests

主程序
import requests # 🚨 IMPORTANT: print the attributes of what you imported print(dir(requests)) def make_request(): # ⛔️ AttributeError: module 'requests' has no attribute 'get' res = requests.get('https://reqres.in/api/users') parsed = res.json() print(parsed) make_request()

但是,我有一个名为的本地文件requests.py,它隐藏了官方
requests模块并导致了错误。

请求.py
def greet(): print('bobbyhadz.com')

当您为模块指定与标准库模块相同的名称时,也会发生这种情况,例如datetime.

sys如果您想知道您的本地模块是否与内置模块冲突,您可以使用该模块打印所有内置模块的名称。

主程序
import sys # 👇️ print all built-in module names print(sys.builtin_module_names)

如果您正在导入的模块之一导入了与您项目中的本地文件同名的模块,也会导致该错误。

例如,如果您导入requestsrequests 导入datetime,但您有一个名为 的本地文件,您仍然会收到错误消息。 datetime.py

Python 解释器
首先

在内置模块中
查找导入的模块,然后在当前目录中查找,然后在 PYTHON PATH 中查找,然后在依赖于安装的默认目录中查找。

因此,当我们创建一个与第三方模块同名的本地文件时,我们实际上用我们的本地文件隐藏了官方模块。

确保您没有使用远程模块的名称命名您的本地模块,例如datetime.pyorrequests.py并删除 import 语句中的任何循环依赖项。

开始调试的一个好方法是print(dir(your_module))查看导入的模块具有哪些属性。

主程序
import requests # ['__builtins__', '__cached__', '__doc__', '__file__', # '__loader__', '__name__', '__package__', '__spec__', 'greet'] print(dir(requests))

如果我们查看导入requests模块的属性,我们可以看到我们的
greet函数,但看不到官方requests
模块的任何实际方法。

这是一个明确的指示,我们正在用我们的本地模块隐藏第三方模块。

确保你没有写错你的导入语句

如果您的导入语句不正确,此方法也可以帮助您。

查看您正在导入的模块的属性,确保您没有错误地编写导入语句。

确保你没有循环导入

错误的另一个常见原因是文件之间存在循环导入。

让我们看一个使用模块first_module.py
second_module.py.

这是代码first_module.py

first_module.py
# 👇️ imports second_module import second_module def first_function(): print('first function') # ⛔️ AttributeError: partially initialized module 'second_module' # has no attribute 'second_function' (most likely due to a circular import) second_module.second_function()

这是代码second_module.py

second_module.py
# 👇️ imports first_module import first_module def second_function(): print('second function') first_module.first_function()

请注意,这两个模块相互导入。这称为循环依赖。

解决两个模块相互依赖的一种方法是将 import 语句嵌套在函数作用域中。

这是更新后的second_module.py文件。

second_module.py
def second_function(): print('second function') # 👇️ now importing in a function scope import first_module first_module.first_function()
现在我们没有在两个模块的最外层范围内导入,导入的顺序不会导致解释器出错。

然而,更好的方法是创建一个third_module.py导入first_modulesecond_module使用它们的文件。

这是更新后的代码first_module.py

first_module.py
def first_function(): print('first function')

这是更新后的代码second_module.py

second_module.py
def second_function(): print('second function')

third_module.py这是使用前面两个模块的代码。

第三个模块.py
import first_module import second_module first_module.first_function() second_module.second_function()

现在我们没有任何循环导入(在相同模块之间导入成员),这使我们的代码更容易推理。

如果您有两个相互导入的模块,那么现在是创建第三个导入前两个模块的好时机。

打印导入模块的所有属性

如果这些建议都没有帮助,请使用该dir()函数打印导入模块具有的所有属性。

主程序
import requests # ['__builtins__', '__cached__', '__doc__', '__file__', # '__loader__', '__name__', '__package__', '__spec__', 'greet'] print(dir(requests))

如果将模块对象传递给
dir()函数,它会返回模块属性名称的列表。

如果您尝试访问不在此列表中的任何属性,您将得到“AttributeError:模块没有属性”。

这意味着您正在尝试访问模块中不存在的属性,或者您的导入语句不正确。

考虑以下示例。

我们有一个名为的模块another_file.py,它有一个Employee类。

另一个文件.py
class Employee: def __init__(self, name): self.name = name def greet(self): return f'Hello {self.name}'

我们有一个名为main.pywhich imports from 的文件another_file.py

主程序
import another_file # ['Employee', '__builtins__', '__cached__', '__doc__', # '__file__', '__loader__', '__name__', '__package__', '__spec__'] print(dir(another_file)) # ⛔️ AttributeError: module 'another_file' has no attribute 'greet' another_file.greet()

请注意,我们正在尝试访问greet模块对象上的方法,即使我们没有首先创建该类的实例。

如果我们查看调用该dir()函数的输出,我们可以看到该模块具有一个Employee属性。

主程序
import another_file emp = another_file.Employee('Bobby Hadz') # 👇️ Hello Bobby Hadz print(emp.greet())

为了解决这个错误,我们首先创建了一个实例并在实例上调用方法,而不是在模块对象上。

结论

要解决 Python“AttributeError: module has no attribute”,请确保您没有使用远程模块的名称命名本地模块,例如
datetime.pyorrequests.py并删除导入语句中的任何循环依赖项。