Here's the disassembly of the code for a simple example module. A code object is a read-only container for bytecode, the constants and names it uses, and metadata about the number of local variables, required stack size, etc. Notice that all of the code objects are compiled as constants. These are created at compilation time. But the objects class A
and function test
are instantiated at execution time (e.g. when the module is imported).
To make the class, BUILD_CLASS
takes the name 'A'
, the bases tuple
(object,)
, and a dict
that contains the attributes of the class namespace. This is like manually instantiating a type by calling type(name, bases, dict)
. To make the dict
, a function is created from code object A
and called. Finally, the class object is stored in the module namespace via STORE_NAME
.
In code object A
, self.z
is loaded on the stack as the argument to MAKE_FUNCTION
. The bytecode op LOAD_NAME
will search for self
in the current locals (i.e. the class namespace being defined), the module globals, and builtins. This will obviously fail if self
isn't defined in the global or builtins scope; it clearly isn't defined in the local scope.
If it did succeed, however, the function would be created with (self.z,)
as its __defaults__
attribute, and then stored to the local name test
.
>>> code = compile('''
... class A(object):
... def test(self, a=self.z): pass
... ''', '<input>', 'exec')
>>> dis.dis(code)
2 0 LOAD_CONST 0 ('A')
3 LOAD_NAME 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 1 (<code object A ...>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_NAME 1 (A)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE
>>> dis.dis(code.co_consts[1]) # code object A
2 0 LOAD_NAME 0 (__name__)
3 STORE_NAME 1 (__module__)
3 6 LOAD_NAME 2 (self)
9 LOAD_ATTR 3 (z)
12 LOAD_CONST 0 (<code object test ...>)
15 MAKE_FUNCTION 1
18 STORE_NAME 4 (test)
21 LOAD_LOCALS
22 RETURN_VALUE
@uselpa: Your pastebin example (rewritten for 2.x):
>>> code = compile('''
... default = 1
... class Cl(object):
... def __init__(self, a=default):
... print a
... Cl()
... default = 2
... Cl()
... ''', '<input>', 'exec')
>>> dis.dis(code)
2 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (default)
3 6 LOAD_CONST 1 ('Cl')
9 LOAD_NAME 1 (object)
12 BUILD_TUPLE 1
15 LOAD_CONST 2 (<code object Cl ...>)
18 MAKE_FUNCTION 0
21 CALL_FUNCTION 0
24 BUILD_CLASS
25 STORE_NAME 2 (Cl)
6 28 LOAD_NAME 2 (Cl)
31 CALL_FUNCTION 0
34 POP_TOP
7 35 LOAD_CONST 3 (2)
38 STORE_NAME 0 (default)
8 41 LOAD_NAME 2 (Cl)
44 CALL_FUNCTION 0
47 POP_TOP
48 LOAD_CONST 4 (None)
51 RETURN_VALUE
As you can see, class object Cl
(and function object __init__
) is only instantiated and stored to the local name 'Cl'
once. The module executes sequentially at run time, so subsequently rebinding the name default
will have no effect on the default value in __init__
.
You could dynamically instantiate a new function using the previously compiled code and a new default value:
>>> default = 1
>>> class Cl(object):
... def __init__(self, a=default):
... print a
...
>>> from types import FunctionType
>>> default = 2
>>> Cl.__init__ = FunctionType(
... Cl.__init__.__code__, globals(), '__init__', (default,), None)
>>> c = Cl()
2
This reuses the already compiled code object from __init__.__code__
to create a function with a new __defaults__
tuple:
>>> Cl.__init__.__defaults__
(2,)