Wie überschreibe ich __setitem__ für eine globale Definition einer Funktion?

Ich möchte in der Lage sein, Variablenzuordnungen innerhalb einer Funktion abzufangen und benutzerdefinierten Code auszuführen. Ich habe versucht, eine benutzerdefinierte dict wie folgt zu erstellen:

class userdict(dict): def __setitem__(self, key, value): print 'run my code' dict.__setitem__(self, key, value) 

Wenn ich den Code mit diesem als globalen Dict ausführe, dann wird mein benutzerdefinierter Code bei jeder Variablenzuweisung ausgeführt. z.B:

 UserDict = userdict() exec 'x = 1' in UserDict #outputs 'run my code' 

Aber wenn mein Code in einer Funktion ist, funktioniert es nicht:

 code = """ def foo(): global x x = 1 """ exec code in UserDict UserDict['foo']() 

In diesem Fall ist 'x' zugeordnet, aber mein benutzerdefinierter Code läuft nicht. Ich nehme an, dass innerhalb einer Funktion das globale Dikt irgendwie modifiziert wird, ohne setitem aufzurufen. Ist das richtig? Gibt es eine Möglichkeit, Variablenzuordnungen innerhalb einer Funktion abzufangen und benutzerdefinierten Code auszuführen?

Ich möchte dies tun, um bestimmte Objekte in einer Funktion mit anderen Objekten in meinem Programm zu synchronisieren. In den Worten, wenn die Zuordnung zu bestimmten Variablen innerhalb der Funktion auftritt, sollte sich diese Änderung zu anderen Variablen in meinem Programm ausbreiten.

  • Lesen und überschreiben Sie eine Datei in Python
  • Schreiben und Ändern einer vorhandenen Arbeitsmappe mit Python
  • Erweiterung der Python's builtin Str
  • Python eingebaute Funktionen gegen magische Funktionen und übergeordneten
  • Python: Multiplikation überschreiben
  • Python: Erweiterung von int und MRO für __init__
  • Wie überschreibe ich einen Python-Import?
  • Odoo: Wie man die ursprüngliche Funktion überschreibt
  • One Solution collect form web for “Wie überschreibe ich __setitem__ für eine globale Definition einer Funktion?”

    Das Problem könnte sein, dass builtin dict Methoden nicht in Overclasses Methoden in CPython überschrieben werden. Pypy, Jython rufen benutzerdefinierte __setitem__() so sehen sie sofort, wenn x gesetzt ist.

    dis Modul zeigt, dass STORE_GLOBAL verwendet wird, um x :

     >>> def f(): ... global x ... x = 1 ... ... >>> import dis >>> dis.dis(f) 4 0 LOAD_CONST 1 (1) 3 STORE_GLOBAL 0 (x) 6 LOAD_CONST 0 (None) 9 RETURN_VALUE 

    Es ist in ceval.c implementiert als:

      TARGET(STORE_GLOBAL) w = GETITEM(names, oparg); v = POP(); err = PyDict_SetItem(f->f_globals, w, v); Py_DECREF(v); if (err == 0) DISPATCH(); break; 

    Wenn PyDict_SetItem() durch PyObject_SetItem() dann arbeitet auch CPython, dh die benutzerdefinierte __setitem__() wird aufgerufen.

    Python ist die beste Programmiersprache der Welt.