为什么会出现 AttributeError: 'NoneType' object has no attribute 'something' 错误?

459

我收到一个错误信息,上面写着

AttributeError: 'NoneType' object has no attribute 'something'
我该如何理解这个信息?

一般有哪些情况可能会导致AttributeError,我又该如何找出问题所在呢?


这是AttributeError的一个特殊情况。它需要单独处理,因为从代码中获取意外的None值有很多种方式,所以通常是不同的问题;对于其他AttributeError,问题可能很容易就是属性名称。

另请参阅什么是None值?什么是“NoneType”对象?了解None及其类型NoneType


2
TODO: 找到一个合适的通用AttributeError规范,以包含在see-also部分中。https://dev59.com/3Ggt5IYBdhLWcg3w-SBM不太合适,因为它是由于混合制表符/空格缩进而引起的2.x特定影响,这会导致答案的混淆和不准确性。 - Karl Knechtel
11个回答

439

NoneType代表你原本认为正在处理的类或对象实例,事实上得到的是None。这通常意味着上方的赋值或函数调用失败或返回了一个意外的结果。


3
记得从函数调用中返回是很有帮助的……试图引用未返回的项通常不会太顺利。我真傻。 - Shrout1
这正是我的问题所在。我经常会回到这里。:D 谢谢。 - rahulspoudel
这对我来说确实是个问题。我经常回来这里。:D 谢谢。 - rahulspoudel

140
你有一个等于None的变量,你尝试访问它的名为“something”的属性。
foo = None
foo.something = 1

或者

foo = None
print(foo.something)

两者都将产生一个AttributeError: 'NoneType'


21
除非你指出人们可能会从某些地方得到None,否则这可能没有帮助。显式的foo = None不太可能是问题所在;问题通常在于foo = something(),而你没有意识到something()在未成功或结果集为空时可能返回None - tripleee
这是完全正确的。例如,当您使用Django开发电子商务应用程序时,您已经处理了购物车功能,并且在测试购物车功能与产品时一切似乎都正常。然后,在后端中删除已注册到购物车的产品。如果您尝试再次转到购物车页面,则会遇到上述错误。必须进行适当的修复以避免此问题。 - Adeolu Temitope Olofintuyi

66

其他人已经解释了NoneType是什么以及导致其出现的常见方式(即从函数中未返回值)。

另一个常见的原因是在可变对象上进行就地操作的赋值,这会导致None出现在您不希望的位置。例如:

mylist = mylist.sort()

sort() 方法可以对列表进行原地排序,也就是说,mylist 被修改了。但是该方法的实际返回值是 None 而不是已排序的列表。因此,你刚刚将 None 赋给了 mylist。如果接下来尝试执行例如 mylist.append(1) 的操作,Python 将会报错。


1
这是一个很棒的解释 - 就像在C#中获得了一个空引用异常一样。变量没有被赋值,是None。谢谢。 - Ken

17

NoneType 是值为 None 的数据类型。在这种情况下,变量 lifetime 的值是 None

这种情况经常发生在调用一个没有 return 的函数时。

然而,有无数种其他方法可以将变量设置为 None。


1
我认为lifetime在编辑前并没有被赋值为None。他试图访问另一个对象的lifetime属性,而该对象的值是None - g.d.d.c

15

考虑下面的代码。

def return_something(someint):
 if  someint > 5:
    return someint

y = return_something(2)
y.real()

这将会给你一个错误:

AttributeError: 'NoneType' object has no attribute 'real'

因此,以下是要点:

  1. 在代码中,一个函数或类方法没有返回任何东西或返回了None
  2. 然后你尝试访问该返回对象的属性(即None),从而导致错误消息。

7
if val is not None:
    print(val)
else:
    # no need for else: really if it doesn't contain anything useful
    pass

检查特定数据是否为空或null。


1
“else: pass”是完全没用的;如果你在“else:”里什么也不需要放,可以直接省略它。 - tripleee

4
这意味着你正在尝试访问的对象是None。在Python中,None是一个空变量(Null)。 这种类型的错误发生是因为你的代码类似于以下内容。
x1 = None
print(x1.something)

#or

x1 = None
x1.someother = "Hellow world"

#or
x1 = None
x1.some_func()

# you can avoid some of these error by adding this kind of check
if(x1 is not None):
    ... Do something here
else:
    print("X1 variable is Null or None")

3

在构建一个估算器(sklearn)时,如果你忘记在fit函数中返回self,你将得到相同的错误。

class ImputeLags(BaseEstimator, TransformerMixin):
    def __init__(self, columns):
        self.columns = columns

    def fit(self, x, y=None):
        """ do something """

    def transfrom(self, x):
        return x

AttributeError: 'NoneType'对象没有属性“transform”?

在fit函数中添加return self可以修复此错误。


1
也许值得指出的是,没有明确“返回”任何内容的函数将隐式地“返回None”。如果您的函数基本上是“if something: return value”,那么当“something”不为真时,它将最终进入隐式的“返回None”状态。(PHINCY L PIOUS的答案详细阐述了这种特殊情况。) - tripleee

1

g.d.d.c.是正确的,但是添加一个非常频繁的例子:

您可能以递归形式调用此函数。在这种情况下,您可能会到达空指针或NoneType。在这种情况下,您可能会遇到此错误。因此,在访问该参数的属性之前,请检查它是否不是NoneType


好的,但是你如何进行那个检查? - not2qubit
if foo is not None: - Gringo Suave
确实,在递归函数中忘记在每种情况下返回某些东西是一个常见的错误;但是,这个答案的阐述似乎不够详细,实际上并没有什么用。请参阅常见的FAQ https://dev59.com/TmMm5IYBdhLWcg3wMs_R - tripleee

0
当您在Flask应用程序中注释掉HTML时,可能会出现此错误。这里qual.date_expiry的值为None:
   <!-- <td>{{ qual.date_expiry.date() }}</td> -->

删除这行或修复它:

<td>{% if qual.date_attained != None %} {{ qual.date_attained.date() }} {% endif %} </td>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接