def myfunc():
return x
x = 10
print(myfunc())
The above codes work, where the free variable x
does not need to be defined when I define myfunc
.
However, the following codes do not work:
class myclass:
func = extfunc
def extfunc(self):
return 'hello'
Here I need to move the definition of extfunc
before the class definition, in order to make the codes work.
Why does class definition need more information of its attributes than what is needed for a free variable in a function definition?
CodePudding user response:
This code:
def myfunc():
return x
defines a function, but doesn't execute the code inside it where x
is until/unless myfunc
is called. The body of the function isn't evaluated when the function definition is evaluated, it's evaluated later when the function is called.
In contrast, in this code:
class myclass:
func = extfunc
the class definition is evaluated in order to create the class, as described in the docs here. So func = extfunc
is evaluated as part of class definition in order to assign a value to the func
variable in the class scope. func
is like a static member in languages that use that terminology.
A more direct comparison would be this:
class myclass:
def example(self):
return x
There, return x
isn't evaluated until or unless example
is called.
See also this example in the documentation:
Attribute references use the standard syntax used for all attribute references in Python:
obj.name
. Valid attribute names are all the names that were in the class’s namespace when the class object was created. So, if the class definition looked like this:class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world'
then
MyClass.i
andMyClass.f
are valid attribute references, returning an integer and a function object, respectively.
In your example, myclass.func
would be a valid reference immediately after the class definition, so func = extfunc
must be evaluated during the class definition, unlike the body of a function.