2012-04-15 5 views
0

Ich möchte eine Klasseneigenschaft festlegen, die von allen Instanzen der Klasse oder ihrer Unterklassen gemeinsam genutzt werden kann. Es sollte für jede Instanz möglich sein, auch die Eigenschaft festzulegen.Klasseneigenschaft, auf die von allen Instanzen (auch von Unterklassen) zugegriffen werden kann.

Ich habe versucht, die folgenden:

class A: 
    x = 1 
    @classmethod 
    def setX(cls, val): 
     if cls.__bases__: 
      cls = cls.__bases__[-1] 
     cls.x = val 

Dies scheint bei einzelnen Erbe zu funktionieren. Aber wenn ich mehrere Vererbung, abhängig von der Reihenfolge der Vererbung, es funktioniert entweder oder nicht (d. H. Klasse A ist nicht immer die letzte Basen).

Irgendwelche Ideen für eine robuste Implementierung?

+3

Setters und Getter sind eine wirklich schlechte Praxis in Python - ich kann nicht sagen, ob dies nur ein Beispiel aus Gründen der Frage ist, oder etwas, das Sie wirklich machen. Wenn das letztere, dann überprüfen Sie die ['' property() 'Builtin /' '@ property'' Decorator] (http://docs.python.org/library/functions.html#property). –

+0

Nur mit 'A.x' funktioniert nicht? –

Antwort

1

Der richtige Weg, IMO, ist mit einem Klasse-Hotel zu gehen. Da Eigenschaften __dict__ an ein Objekt der Klassen gebunden, im Gegensatz zu den eigenen __dict__ des Objekts und da Ihr Objekt passiert, um eine Klasse zu sein, können Sie es auf die Klassen Klasse anhängen muss, seine Metaklasse:

class A(object): 

    _x = None 

    class __metaclass__(type): 

     @property 
     def x(cls): 
      return A._x 

     @x.setter 
     def x(cls, val): 
      A._x = val 


class B(A): 
    pass 

A.x = 'jim' 
B.x = 'joe' 

print A.x, B.x 

Ergebnis:

joe joe 

auch Ihre Klassen Klassen neuen Stils sein muss, dh sie von object in Python 2.x erben müssen Und metaclasses sind unterschiedlich definiert in Python 3.x:

class MetaA(type): 
    """ like ___metaclass__ above """ 

class A(metaclass=MetaA): 

    _x = None 

... 
2

Verwenden lexikalischer Scoping:

class A(object): 
    x = 1 
    @classmethod 
    def setX(cls, val): 
     A.x = val 
Verwandte Themen