Wie kann man Variablen eines anderen Bereichs ändern?

Currectly, ich versuche folgendes: Einige mutator Funktion akzeptiert den lokalen Bereich der anderen Funktion mit locals()

 def mutator(locals): locals['n'] = 10 locals['l'].append(10) def f(): n = 1 l = [1] mutator(locals()) print(n,l) # >>> 1, [1,10] f(None) 

Und das funktioniert wie erwartet: Ich war in der Lage, veränderliche Listeninhalte zu modifizieren, aber es versäumt, einen anderen unveränderlichen int auf den gleichen Namen zu "rebinden".

Derzeit sehe ich einige Optionen:

  • eval() , exec() & Co
  • Spiel mit Stapelrahmen und lokalen Variablen in mutator()
  • Halten Sie solche Variablen in einem dict : nicht sehr praktisch aber wahrscheinlich das beste

Die Einschränkung lautet: Zielfunktion f() kann nur einen Funktionsaufruf enthalten, evtl. mit Argumenten, und diese Funktion sollte in der Lage sein, Werte im f() s aktuellen Bereich zu ändern.

Also … gibt es einen Weg, um den Wert der Variablen wieder einzuführen (bind ein anderes Objekt) zur Laufzeit? Ich glaube nicht, dass es keinen guten Trick gibt, dies zu erreichen!


Hier ist ein Beispiel für die Sache, die ich versuche zu erreichen:

 def view(request): # Yes, that's Django! q = MyModel.objects.all() data = { 'some_action': True, 'items_per_page': 50 } # defaults. Mutators can change this mutators.launch(locals(), data ) # Launch mutators that may want to narrow the QuerySet if data['some_action']: # do something useful if no mutator has disabled it ... # paginate using data['items_per_page'] 

Ich möchte nicht die data dict hier: Fähigkeit, sie zu ändern, wie lokale Variablen wäre viel besser & hübsch. Beachten Sie, dass q QuerySet-Objekt veränderlich ist und Mutatoren können ihren Inhalt ändern.

2 Solutions collect form web for “Wie kann man Variablen eines anderen Bereichs ändern?”

 class AttributeCollection(object): pass shared_settings= AttributeCollection() # now improvise shared_settings.temperature= 30 shared_settings.samples= [] # etc 

Pass, dass shared_settings herum, oder machen es global, und legen Sie seine Attribute auf was auch immer Sie wünschen.

Sie sehen, die locals() einer Funktion sind nur ein Namespace gemeint (und optimiert dafür), um innerhalb dieser Funktion manipuliert zu werden (und während diese Funktion läuft). Verwenden Sie einen anderen Namespace (in meinem Vorschlag, das shared_settings Objekt) als einen gemeinsamen Spielplatz für Ihren Code.

Mach es so:

 def mutator(l): l.append(10) return 10 def f(): n = 1 l = [1] n = mutator(l) print(n,l) # >>> 1, [1,10] f() 

Ja, ich weiß, es ist nicht der kluge Hack, den du willst Aber es funktioniert. 🙂

Wenn Sie eine Reihe von globalen Konfigurationsoptionen wünschen, die Sie einschalten und abstimmen können, halten Sie sie alle auf einem Objekt:

 class Settings(object): def __init__(self): self.n = 1 self.l = [1] 

Jetzt kannst du die Variablen zu deinem Herzen Inhalt ändern.

  • Python: Wie erfasse ich eine Variable, die in einem nicht globalen Ahnenumfang angegeben ist?
  • Den Block der Befehle, die in der mit Anweisung ausgeführt werden sollen
  • Wie kann man neue Scopes in Python schaffen?
  • Warum erbt keine Unterfunktion den Bereich in Python?
  • Funktion Ortsname Bindung aus einem äußeren Bereich
  • Warum ist der Ort zum Zeitpunkt der Kompilierung bestimmt?
  • Zweifel über python variablen Bereich
  • Variabler Bereich (Python Newbie)
  • Warum können Funktionen in Python-Druckvariablen im Umschließungsbereich funktionieren, können sie aber nicht in der Zuordnung verwenden?
  • Python - Wie man eine globale Variable aus einer Funktion
  • Pythonumfang [doppelte]
  • Python ist die beste Programmiersprache der Welt.