Override -Class Attribut-Getter

Ich definiere eine Debug-Klasse wie folgt:

_debug = False class Debug: DrawOutlines = True InvinciblePlayer = True 

Ich möchte die Debug Klasse überschreiben, so dass, wenn _debug False ist, jedes Klassenattribut von Debug (das existiert) False sein würde. Welche __ Funktion __ gehe ich aus, um zu ändern, wie Klassenattribute aufgerufen werden?

Bearbeiten:

Ich weiß, dass einfach übergeordnetes __getattribute__ nicht für Klassenattribute funktioniert:

 >>> _debug = False False >>> class Debug: ... DrawOutlines = True ... ... def __getattribute__(self, name): ... return _debug and object.__getattribute__(self, name) ... >>> Debug.DrawOutlines True >>> Debug.cake Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'Debug' has no attribute 'cake' 

Wäre das ein Fall, wo ich eine Metaklasse brauchen würde?

  • Problem beim Ausführen eines Python-Programms, Fehler: Name 's' ist nicht definiert [Duplizieren]
  • Wie kann ich einen Coroutine als normale Funktion in Event Loop verpacken?
  • Python: Zwei Module und Klassen mit dem gleichen Namen unter verschiedenen Paketen
  • Wie konvertiere ich einen String in einen Puffer in Python 3.1?
  • Python3: bind-Methode zur Klasseninstanz mit .__ get __ (), es funktioniert aber warum?
  • Hinzufügen von Scores in Abhängigkeit von ihren Regionen (long / latitude) in Python-Asisstanz
  • Namespace vs regelmäßiges Paket
  • Asterisks außerhalb von Funktionsaufrufen
  • 2 Solutions collect form web for “Override -Class Attribut-Getter”

    Ja, du brauchst eine Metaklasse, denn wenn du __getattribute__ in der Klasse Debug definierst (was __getattribute__ eine neue Klasse sein muss), __getattribute__ Python das für Attribut-Lookups gegen Instanzen von Debug an, aber nicht für Attribut-Lookups gegen Debug selbst.

    Das macht Sinn, denn Debug.__getattribute__ ist definiert, um auf Instanzen von Debug zu arbeiten, nicht die Klasse Debug. (Sie könnten sich vorstellen, eine Klassenmethode __getattribute__ , aber ich kann keine Beweise dafür finden, dass Python irgendwelche Maschinen hat, die so etwas anrufen würden.)

    Das erste, was ich hier dachte, ist, ein weiteres __getattribute__ hinzuzufügen, in dem Python es nach Debug-Class-Attribut-Lookups suchen würde, nämlich in der Klasse, in der die Debug-Klasse eine Instanz ist: Debug.__class__.__getattribute__ .

    Das gibt es und funktioniert wie man es erwarten würde:

     >>> Debug.__class__.__getattribute__(Debug, 'Draw') True >>> Debug.__class__.__getattribute__(Debug, 'Bogus') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in __getattribute__ AttributeError: 'DebugType' object has no attribute 'Bogus' 

    Aber es ist nicht modifizierbar:

     >>> Debug.__class__.__getattribute__ = Debug.__getattribute__ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't set attributes of built-in/extension type 'type' 

    Dies scheint nur eine Tatsache des Lebens mit der Python-Implementierung zu sein. Während das Konzept existiert, ist es nicht erlaubt, Attribute von eingebauten Typen zu ändern, damit dieser Ansatz nicht funktioniert.

    Allerdings Metaclasses zur Rettung. Sie wissen wahrscheinlich schon, wie dies zu tun ist, aber für andere Leser werde ich ein Beispiel geben (und es gibt ein anderes Beispiel in dieser Antwort , auf die meine Antwort schuld etwas schuld).

     _debug = True >>> class DebugType(type): ... def __getattribute__(self, name): ... print 'attr lookup for %s' % str(name) ... return _debug and object.__getattribute__(self, name) ... >>> class Debug(object): ... Draw = True ... __metaclass__ = DebugType ... >>> _debug False >>> Debug.Draw attr lookup for Draw False >>> _debug = True >>> Debug.Draw attr lookup for Draw True 

    Also, um es zu kochen, ist die Standard-Klassenimplementierung für Klassen type , also ist das Standardattribut-Looker-Obere für Klassenattribute type.__getattribute__ , und Sie können den type.__getattribute__ direkt ändern oder ersetzen, aber Sie können den type mit dem Metaclass-Mechanismus ersetzen , Und, wie im obigen Beispiel, ersetzen Sie es mit einer Unterklasse des type , die die __getattribute__ Sie wollen.

    Sie überschreiben __getattribute__ , um alle Attribut-Zugriff abzufangen, oder __getattr__ , um nur für Attribute aufgerufen zu werden, die nicht vorhanden sind:

     _debug = True class A(object): def __getattribute__(self, attr): if _debug: print attr return object.__getattribute__(self, attr) 
    Python ist die beste Programmiersprache der Welt.