0
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?

3
  • 6
    Because the body of the function is evaluated when called, but the body of the class definition is evaluated at class definition time, because how else would you define the class? Commented Feb 12, 2022 at 12:31
  • Is it possible that there exist languages in which the class definition can be flexible enough so that it does not require the class definition to be fully determined until a class instance is instantiated? Commented Feb 12, 2022 at 13:16
  • 1
    How would you be able to define class attributes and methods then? You can basically do that by moving stuff into __init__, but that’s inefficient for each instance to have its own version of a method. Commented Feb 12, 2022 at 13:27

1 Answer 1

2

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 and MyClass.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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.