NameError:名称'self'未定义说明

时间:2020-01-30 13:05:31

标签: python python-3.x

我试图了解“自我”的工作方式。在第一个代码中,我遇到了错误,但是我相信我做对了所有事情。在那之后,我尝试了一些其他的事情来解决它,但是没有。我在这里想念什么?

class myClass:
    def foo(self):
            print('WORKED')
    self.foo()

NameError:名称“ self”未定义


class myClass:
    def foo(self):
            print('WORKED')
    foo()

TypeError:foo()缺少1个必需的位置参数:“ self”


   class myClass:
       def foo():
               print('WORKED')
       foo()
   myClass.foo() 

工作

(在这里pylint会给出警告,说“方法没有参数”)


3 个答案:

答案 0 :(得分:1)

正确的用法是:

binary archives

您必须使用参数class MyClass: def foo(self): print('WORKED') def bar(self): self.foo() obj = MyClass() obj.bar() 定义方法。调用self时,它将作为obj自动传递。也就是说,obj.foo()等效于obj.foo()

答案 1 :(得分:0)

为什么?

class myClass:
    def foo(s):
        print('WORKED', s)
        return s
    s = foo(1)
    print("Hello")
myClass.foo(2) 
print(myClass.s)

Result

WORKED 1
Hello
WORKED 2
1

因此,如果您在没有foo()的情况下调用self,它将被视为一个类字段。如果您省略了字段声明(即s = foo(1)直接为foo(1)),它也会(作为您的代码)执行,但不会在任何地方存储结果。

您不能s = self.foo(1),因为self不会在成员函数之外定义。但是,您可以直接调用它s = foo(1)并将其存储在成员s

答案 2 :(得分:0)

其他人提供了运行代码的示例,但是我认为还有一个更深层次的问题,就是不了解 Python 的工作方式。

这里要理解的是,与其他语言(如Java或C#)不同,在Python中,类的“主体”是代码块,该代码块在创建类时执行。 / p>

class创建一个特殊的作用域,然后运行主体内部的所有内容,然后使用在类主体中收集的所有符号创建类。它也不同于Ruby,后者首先创建类,然后执行主体(并且它具有表示类本身的self,您可以调用类似attr_accessor的方法):在Python中,首先执行主体然后创建该类。

要注意的另一件事是,在Python self中并不是完全神奇,而是在编写obj.foo()时Python将其执行为type(obj).foo(obj)。从技术上讲,您甚至不必调用第一个参数self

这意味着:

  • 在您的第一个代码段中,在定义了方法之后,您立即尝试在甚至不存在的点上调用它(您尚未创建可以调用的self
  • 在第二个片段中,该函数存在于范围中,但尚未转换为方法,因此它仍在等待一个位置参数。
  • 在您的第三个代码段中,该函数存在于作用域中,并且不带任何参数,您可以调用它,但是,如果您之后尝试在某个实例上调用它,则它将无法正常工作 li>

PS:本质上您可以想到:

class Foo:
    ...

作为速记

def Foo_body:
    ...
    return locals()
Foo = type("Foo", (object,), Foo_body())