名称错误:未定义名称 'self'

188

为什么要这样的结构

class A:
    def __init__(self, a):
        self.a = a

    def p(self, b=self.a):
        print b

为什么出现错误 NameError: name 'self' is not defined

3个回答

204
默认参数值是在函数定义时进行评估的,但self仅在函数调用时可用。因此,参数列表中的参数无法相互引用。
将参数默认值设置为None并在代码中添加测试是一种常见模式:
def p(self, b=None):
    if b is None:
        b = self.a
    print b
更新 2022: Python 开发者现在正在考虑在未来的 Python 版本中使用 延迟绑定参数默认值

7
尽管我认为上述内容不太美观(我来自Ruby,那里的事情都能正常工作),但上述内容实际上可以作为解决方法。仍然很尴尬的是Python选择在参数列表中不提供self。 - shevy
4
在Python中,“self”没有特殊的意义,它只是惯例上选择的第一个参数的名称。你也可以用“me”或“x”来代替“self”。 - Max
2
有没有更好的方法来做这件事?如果我们有一个函数,它需要引用self的一打默认参数,我们真的需要一打if语句吗?这太笨拙了。 - Richard J. Barbalace
如果调用者显式地将第二个参数传递为None,它会被覆盖为self.a,这是意料之外和令人惊讶的。 - abelenky

20

如果您还希望将'b'选项设置为None的情况:

def p(self, **kwargs):
    b = kwargs.get('b', self.a)
    print b

16

如果在方法签名中没有定义self,也会发生NameError错误。由于预期和给定的参数不匹配,此错误通常会出现为TypeError。但是,如果您接受可变数量的参数,则self将是arg[0],而变量self将未定义。

这里有一个最简示例。

class Obj:
    def foo(*args):
        print(self.bar)

>NameError: name 'self' is not defined

更正:

class Obj:
    def baz(self, *args):
        print(self.bar)

[1] 为什么明确的self参数必须保留


这个例子在普通情况下没有意义。从一个方法中省略掉 self 参数通常会导致一个 TypeError 错误,抱怨参数数量不正确。 - Karl Knechtel
不一定,考虑一个方法应该是 foo(self, *args, **kwargs) 但是self被省略的情况。 - Erich
合理,但不常见,肯定不符合这个例子。 - Karl Knechtel
你说得对。然而,在我的情况下,给出的错误信息是标题中的那个。通过互联网查询,您会来到这里。在stackoverflow上是否有其他问题可以指向?我很乐意将此答案替换为指向另一个主题的问题评论。 - Erich
然而,在我的情况下给出的错误信息是标题中的那一个。从所展示的代码来看,是的;但在这种情况下,“foo”不能被称为“类函数”(你是否想说方法?),因为没有任何类可见。如果将代码缩进到一个类中,然后用作方法,错误消息将不同——要获取此消息还需要将“foo”调用为类内的普通函数命名空间,此时代码作者除了笔误之外还存在严重的概念难题。 - Karl Knechtel
我已经重新改写了我的答案,请看一下。我的先前示例足以为self生成“NameError”,但不反映我所描述的真实世界示例。 我现在的示例与一个明确的案例相一致。之前未定义类的原因是为了凸显self只是一个变量的事实,并且NameError意味着变量未定义。我的示例产生了这样的错误。就像标题中所说的那样。这是“NameError:'self' ...”某些搜索引擎结果的第一页。我认为在此提及对于初学python的人来说很重要。 - Erich

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