Why Does a Class' Body Get Executed at Definition Time

Why does a class' body get executed at definition time?

Everything is executed at the module level when Python first imports a module. Function bodies (and generator expression bodies) are the exception here, not the rule. Python executes everything to create the objects contained in a module; like everything in Python, classes are objects, and so are functions.

The only reason a class body uses a separate code object is because a class body is executed in a separate namespace, with that namespace then forming the class attributes. Class bodies are not the only such namespaces; set and dict comprehensions, and in Python 3, list comprehensions are also executed with a separate namespace, scoping their locals.

So functions and generator expressions are the exception, expressly because their whole purpose is to be executed at a later time. Note that the function definition is executed:

>>> import dis
>>> dis.dis(compile('def foo(): pass', '<stdin>', 'exec'))
1 0 LOAD_CONST 0 (<code object foo at 0x106aef2b0, file "<stdin>", line 1>)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (foo)
9 LOAD_CONST 1 (None)
12 RETURN_VALUE

The MAKE_FUNCTION bytecode there creates the function object, together with the stored bytecode for that function, and the result is bound to the global name foo.

Class objects are no different here; the class statement produces a class object, and as part of that object, we need to know the attributes from the class body.

If Python did not execute the class body, other code could not make any use of those class members. You couldn't access class attributes (including class methods and static methods), you couldn't set class attributes, etc.

Any functions that are part of the class body are of course not executed at that time. Just like top-level functions, only a MAKE_FUNCTION bytecode is executed and the resulting local name (set with STORE_FAST) is then turned into a class attribute, analogous to a global function object being bound to a global with STORE_NAME.

In python,why does the code in class body gets executed only when a method of another module is called?

Programming languages can have several different kinds of syntactic elements. Most languages, for example, will have statements and expressions, which are distinct. Some languages, like Java, have other syntactic elements at the top level. You cannot, for example, write some statements at the top level or in a class, but if you wanted to put a class definition at the top level or method in a class, that would be just fine.

You could, perhaps, think of Java as having a declarative part at the top level that switches to imperative (statements) once you go deeper, and then likely an expression as you go even further. But Python doesn’t really work that way. Python does have a distinction between expressions and statements, but it doesn’t really have a top-level declarative syntactic element. Perhaps you’re thinking of this:

def greet(name):
print("Hello, {}!".format(name))

…in the same way as you would in Java, in that it can only appear in a certain context. But no: in Python, a function definition is a statement, as is a class definition, as is an assignment.

Because of this design, it’s infeasible to “just import the definitions”: in order for the definitions to be created, the code to create the definitions must be run.

I urge you to think of the following case. In Python, if you want to create an enumeration (without the fancy new enum module), you might do something like this:

FOO, BAR, BAZ = range(3)

To the human eye, that’s probably a definition we want to exist when we import the module. But how is that fundamentally different from something like this, which you might expect to exist in __main__?

name = input("What's your name? ")

There really is no difference, so Python makes no attempt to try to distinguish them; when you import a module, the code is executed.


Bonus: Similar behavior in Java

Think about this:

public class Test {
static {
System.out.println("Wait, what? Code is running without being called?");
}

public static void main(String[] args) {
System.out.println("Nothing to see here, move along now...");
}
}

Python: Why does class variable get assigned?

The code evaluates the class when you execute it, and calls the print to define the class variable value.

The below example shows that it's printed before the instanciation.

class MyClass:

def __init__(self):
self.value = 0

def set_value(self, value):
self.value = 5

def get_value(self):
return self.value

value = print("Hello")

print('hi')
a = MyClass()

#output
>>> Hello
>>>hi

Print statement in class getting executed even though there is no class instance/object

The class body executes at class definition time, and that's how the language is designed.

From section 9.3.1 Class Definition syntax:

In practice, the statements inside a class definition will usually be function definitions, but other statements are allowed, and sometimes useful.

That is simply how the execution model works in Python, so there's not much more to say about it.

as per my understanding...anything class can not run until we call it by creating a object

Simply a misunderstanding. This applies for def, i.e. function blocks, but not for class blocks.

Why the code inside a class is executed when defined but a code inside a function is not executed until it gets called?

That statement is not part of any method like __init__ or any method inside the class. As this statement is not a part of any method, the interpreter executes it before invoking the __init__ method (implicit in this case). Invoking the __init__ method means when the __init__ is called when you create an object of this class. That's why this prints it out.

Also another nice point, this would be executed multiple times when you instantiate the object. Because it is only when the interpreter is getting the class definition it executes that once. (From a discussion with Iain Shelvington)

It would be more clear from this output.

class Calc:
print ("Class .. calculating")
print(ab) #throws error
def __init__(self):
print('init')

In this case, if ab is not used earlier then it will throw you error. Very important thing is: the namespace it belongs to, check this:

class Calc:
print ("Class .. calculating")
ab=2
def __init__(self):
print('init')
print(ab) #throws error

Now it will again throw error. Since it is declared inside the class. But you can instantiate the object of the class and access it as something that is part of the class scope.

class Calc:
print ("Class .. calculating")
ab=2
def __init__(self):
print('init')

calc = Calc()
calc.ab # 2

You can check this for further reference. I want to just highlight the subtlety involved in this scope

When a class definition is left normally (via the end), a class object
is created. This is basically a wrapper around the contents of the
namespace created by the class definition; we’ll learn more about
class objects in the next section. The original local scope (the one
in effect just before the class definition was entered) is reinstated,
and the class object is bound here to the class name given in the
class definition header (ClassName in the example).

Why is expression/statement/variable executed before object init?

Code inside a class statement is executed immediately, as part of executing the class statement. Your code is roughly equivalent to

# Execute the body of the class statement
print("hello")
value = 44
def __init__(self):
print("init")

# Call type, passing names defined in the body as a dict
# as the third argument
A = type("A", (), {'value': value, '__init__': __init__})

# Clean up the names, as they are not left in the global namespace
del value, __init__

Once the class A is defined, the only code that gets executed upon instantiation is the body of _init: a = A() is roughly equivalent to

a = A.__new__(A)
a.__init__()

What is the significance of class body being executable?

For a couple of easy examples:

It allows things like attribute accessors to work:

class Dog
attr_reader :name
end

attr_reader and others from that family are just methods that are executed in context where self is a class object. They are not declaractions; they actually execute as the class is being executed. It thus hinges on the ability of Ruby to call methods while defining a class.

It allows conditional definition:

class OptimisedClass
if defined? JRUBY_VERSION
def do_stuff
jruby_optimised_stuff
end
else
def stuff
c_optimised_stuff
end
end
end


Related Topics



Leave a reply



Submit