Class construction
Marcin Szamotulski
mszamot at gmail.com
Mon Oct 21 18:57:41 EDT 2013
You can inspect the process in this way:
>>> c = 'class A: pass'
>>> code = compile(c, '<stdin>', 'exec')
>>> from dis import dis
>>> dis(code)
1 0 LOAD_BUILD_CLASS
1 LOAD_CONST 0 (<code object A at 0x7effeef1c300, file "<stdin>", line 1>)
4 LOAD_CONST 1 ('A')
7 MAKE_FUNCTION 0
10 LOAD_CONST 1 ('A')
13 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
16 STORE_NAME 0 (A)
19 LOAD_CONST 2 (None)
22 RETURN_VALUE
(this is in Python3.3, in Python2.7 the result will be different)
Now you can check ceval.c (PyEval_EvalFrameEx function) what are the
above opcode's doing. For example LOAD_BUILD_CLASS pushes the buildin
function builtins.__build_class__ to the stack and then CALL_FUNCTION
calls it. the c implementation of __build_class__ is in
Python/bltinmodule.c (builtin___build_class__). Indeed this function
will call the metaclass->tb_new `method` (but before it will also call
the __prepare__ method on metaclass to get the namespace). The first
argument on builtin__build_class__ is a function object which correspond
to the class body, and it is evaluated in the class namespace.
So the process (with some simplifications) goes like this:
1. get metaclass: meta
2. call meta.__prepare__ to get namespace (class __dict__)
3. evaluate the class body in the namespace
4. call meta with arguemnts: name, bases, namespace
(when you instantiate any class in Python, metaclass is just
a class, first its __new__ method is called, and then its __init__)
All this is in builtin__build_class__.
I hope it helps,
Regards,
Marcin
On 08:08 Mon 21 Oct , Demian Brecht wrote:
> Hi all,
>
> I'm trying to wrap my head around how classes are constructed at the
> interpreter level (as a side effect of digging into metaclasses) and
> I'm hoping to have my investigation either validated or ridiculed ;)
>
> The pipeline that I've figured through some gdb debugging (starting at
> type_call):
>
> + type_call
> + is there a metaclass for this object?
> + return metaclass->tp_new
> + roughly 350 LOC constructing the type
> + is object is not a subclass of type?
> + return object
> + call obj->tp_init
>
> Does that sound correct? My C/gdb skills are horribly rusty at this
> point so expert insight would help :)
>
> Thanks,
>
> --
>
> Demian Brecht
> http://demianbrecht.github.com
> --
> https://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list