Sollte ich einen Metaklas, einen Klassendekorator verwenden oder die __New__ -Methode überschreiben?

StackOverflow https://stackoverflow.com/questions/2503676

  •  21-09-2019
  •  | 
  •  

Frage

Hier ist mein Problem. Ich möchte, dass die folgende Klasse eine Reihe von Eigenschaftsattributen hat. Ich könnte sie entweder alle wie schreiben wie foo und bar, oder basierend auf einigen anderen Beispielen, die ich gesehen habe, sieht es so aus, als könnte ich einen Klassendekorator, einen Metaklas verwenden oder das überschreiben __new__ Methode zum automatischen Einstellen der Eigenschaften. Ich bin mir einfach nicht sicher, wie der "richtige" Weg es wäre.

class Test(object):
    def calculate_attr(self, attr):
        # do calculaty stuff
        return attr

    @property
    def foo(self):
        return self.calculate_attr('foo')

    @property
    def bar(self):
        return self.calculate_attr('bar')
War es hilfreich?

Lösung

Magie ist schlecht. Es macht Ihren Code schwerer zu verstehen und zu warten. Sie brauchen praktisch nie Metaklasse oder __new__.

Es sieht so aus, als könnte Ihr Anwendungsfall mit ziemlich einfachem Code implementiert werden (mit nur einem kleinen Hauch von Magie):

class Test(object):
    def calculate_attr(self, attr):
        return something

    def __getattr__(self, name):
        return self.calculate_attr(name)

Andere Tipps

Ein Metaclass's __new__ wird nicht der __new__ Für die Klasse, die Sie erstellen - es wird verwendet, um die Klasse selbst zu machen. Das Aktuelles Klassenobjekt wird durch die Metaklasse zurückgegeben. Eine neue Instanz einer Klasse wird von zurückgegeben __new__.

Betrachten Sie den folgenden (verrückten) Code:

def MyMetaClass(name, bases, dict):
    print "name", name
    print "bases", bases
    print "dict", dict
    return 7

class C('hello', 'world'):
    __metaclass__ = MyMetaClass

    foo = "bar"

    def baz(self, qux):
        pass

print "C", C

(Ich habe eine Funktion anstelle einer Klasse als Metaklas verwendet. Jeder Anruf kann als Metaklas verwendet werden, aber viele Menschen entscheiden sich dafür, ihre als Klassen zu korrigieren, von denen er erben type mit neu überschrieben. Die Unterschiede zwischen einer Funktion sind subtil.)

Es gibt aus

name C
bases ('hello', 'world')
dict {'baz': <function baz at 0x4034c844>, '__module__': '__main__', 'foo': 'bar', '__metaclass__': <function MyMetaClass at 0x40345c34>}
C 7

Hilft Ihnen das besser zu verstehen, was Metaklasse ist? sind?

Du wirst sehr selten Müssen eine eigene Metaklasse definieren.

Metaclass wird verwendet, wenn eine neue Klasse - nicht Instanz - erstellt wird. Auf diese Weise können Sie beispielsweise Klassen registrieren (Django macht es und verwendet es beispielsweise, um Tabellen in der Datenbank zu erstellen). Seit class ist eine Anweisung, die Sie als Dekorateurin für eine Klasse betrachten können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top