简体   繁体   中英

NameError: name 'self' is not defined Explain

I'm trying to understand how "self" works. In this first code I got error but I belive I did everything right. After that I try few more things to figure it but could not. What am I missing here?

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

NameError: name 'self' is not defined


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

TypeError: foo() missing 1 required positional argument: 'self'


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

WORKED WORKED

(in here pylint give warning that says "Method has no arguments")


The correct usage is:

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

    def bar(self):
        self.foo()


obj = MyClass()
obj.bar()

You have to define the method with the parameter self . It will be automatically passed as obj when calling obj.foo() . That is, obj.foo() is equivalent to MyClass.foo(obj) .

Why?

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

So if you call foo() without self it will be considered as a class field. If you ommited field declaration (ie s = foo(1) being foo(1) directly) it will execute also (as your code) but will not store result anywhere.

You cannot s = self.foo(1) , because self will not be defined outside a member function. However, you can call it directly s = foo(1) and store in member s

Others have provided examples of code which runs, but I think there's a deeper issue of not understanding how Python works.

The thing to understand here is that unlike other languages like Java or C#, in Python the "body" of a class is a block of code which gets executed during the creation of the class.

class creates a special scope, then all the inside the body is run, then the class is created using all the symbols collected in the class body. It's also different from Ruby where first the class is created then the body is executed (and it has a self representing the class itself and you can call methods like attr_accessor ): in Python first the body is executed then the class is created.

An other thing to note is that in Python self is not exactly magical, rather when you write obj.foo() Python executes it as type(obj).foo(obj) . Technically you don't even have to call the first parameter self .

This means:

  • in your first snippet, right after your defined the method you tried to call it on something which doesn't even exist a this point (you've not created a self you could call)
  • in your second snippet, the function exists in the scope but it's not been converted to a method yet, so it's still waiting for one positional parameter.
  • in your third snippet, the function exists in the scope and takes no parameters and you can call it, however if you try to call it on an instance afterwards it's not going to work properly

PS: essentially you can think of:

class Foo:
    ...

as a shorthand for

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM