python s'appuie sur la variable __class__
pour être dans un cell
pour un appel super()
. Il obtient cette cellule à partir des variables free
dans le premier cadre de pile.où la variable `__class__` est-elle stockée en python, ou comment le compilateur sait-il où le trouver
La chose étrange est cependant que cette variable n'est pas dans locals()
, et il est lorsque vous venez de la référence à partir de la méthode __init__
.
Prenez par exemple ce morceau de code:
class LogicGate:
def __init__(self,n):
print(locals())
a = __class__
print(locals())
Lorsque vous démonter l'appareil, vous pouvez le voir en quelque sorte sait que print
et locals
sont globals et __class__
est un LOAD_DEREF
. Comment le compilateur le sait-il, avant d'exécuter le code? locals
, print
et __class__
ne sont que des noms de variables pour le compilateur autant que je sache. De même, __class__
est tout à coup dans le locals()
avant même qu'il ne soit copié dans a
.
4 10 LOAD_DEREF 0 (__class__)
tout locals
:
2 LOAD_GLOBAL 1 (locals)
Je demande parce que je travaille sur Skulpt un python à javascript compilateur. Et actuellement ce compilateur ne fait pas la différence entre print
ou __class__
et tente de les obtenir tous les deux de la portée globale.
Comme vous pouvez le voir sur l'impression de la ast du peu au-dessus du code, l'analyseur ne fait pas de distinction entre locals
ou __class__
:
Module(body=[ClassDef(name='LogicGate',
bases=[],
keywords=[],
body=[FunctionDef(name='__init__',
args=arguments(args=[arg(arg='self',
annotation=None),
arg(arg='n',
annotation=None)],
vararg=None,
kwonlyargs=[],
kw_defaults=[],
kwarg=None,
defaults=[]),
body=[Expr(value=Call(func=Name(id='print',
ctx=Load()),
# here's the load for locals
args=[Call(func=Name(id='locals',
ctx=Load()),
args=[],
keywords=[])],
keywords=[])),
Assign(targets=[Name(id='a',
ctx=Store())],
# here's the load for __class__
value=Name(id='__class__',
ctx=Load())),
Expr(value=Call(func=Name(id='print',
ctx=Load()),
args=[Call(func=Name(id='locals',
ctx=Load()),
args=[],
keywords=[])],
keywords=[]))],
decorator_list=[],
returns=None)],
decorator_list=[])])
Je trouve une partie si la question, en python2 vous ne pouvez pas faire référence '__class__' de nulle part. Et ce n'est pas à un DEREF. – albertjan
Utilisez-vous python 2 ou python 3? La cellule '__class__' est un hack Python 3 permettant d'appeler' super' sans arguments. – Dunes