Yeni ifadeler iç içe geçmiş bayt kodunda saklanır. Sen başka bir kod nesne yüklenmiş olduğundan sizin sökme görebilirsiniz:
9 LOAD_CONST 1 (<code object A at 0x1004ebb30, file "test0.py", line 4>)
yerine o kod nesneyi incelemek gerekir. Bunun nedeni sınıf gövdesinin bir işlev nesnesi gibi yürütüldüğü ve daha sonra üretilecek yerel ad alanının sınıf üyelerini oluşturmak için kullanıldığıdır.
Demo:
>>> import dis
>>> def wrapper():
... class A(object):
... pass
...
>>> dis.dis(wrapper)
2 0 LOAD_CONST 1 ('A')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object A at 0x104b99930, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (A)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
>>> dis.dis(wrapper.__code__.co_consts[2])
2 0 LOAD_NAME 0 (__name__)
3 STORE_NAME 1 (__module__)
3 6 LOAD_LOCALS
7 RETURN_VALUE
Bu sizin ilk örneği olarak aynı kurulum olduğu; sınıf gövdesine wrapper.__code__.co_consts
tuple ile erişilir, LOAD_CONST
bayt kodu; endeks 2
olarak verilmiştir.
Şimdi bir sınıf gövdesini ekleyebilirsiniz:
>>> def wrapper():
... class A(object):
... print 'hello'
... 1+1
... pass
...
>>> dis.dis(wrapper)
2 0 LOAD_CONST 1 ('A')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object A at 0x104b4adb0, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (A)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
>>> dis.dis(wrapper.__code__.co_consts[2])
2 0 LOAD_NAME 0 (__name__)
3 STORE_NAME 1 (__module__)
3 6 LOAD_CONST 0 ('hello')
9 PRINT_ITEM
10 PRINT_NEWLINE
4 11 LOAD_CONST 2 (2)
14 POP_TOP
5 15 LOAD_LOCALS
16 RETURN_VALUE
Şimdi sınıf gövdesi görünür; Sınıf gövdesi yüklendiğinde çalıştırılacak bayt kodunu görebiliriz.
Not, her sınıf gövdesi için yürütülen LOAD_NAME
ve STORE_NAME
bayt kodlarıdır; Bunlar modül adını alır ve bunları yeni bir yerel ad olarak __module__
olarak depolar, böylece sınıfınız oluşturulduktan sonra bir __module__
özniteliği ile sona erer.
LOAD_LOCALS
bayt kodu daha sonra bu 'işlevi' üretilen tüm yerel isimleri toplar arayana, BUILD_CLASS
bayt kodu 'A'
dize ve (BUILD_TUPLE
ile oluşturulan) object
bazlar başlığın ile birlikte kullanan, böylece bu olabilir döndürür yeni sınıf nesnesini üretin.
Sweet. Bunu bilmiyordum. İlginç soru ve hoş bir cevap. (1) – NPE