2009-06-19 11 views
19

Czy istnieje sposób na odwołanie się do nazwy klasy z deklaracji klasy? przykład następująco:Definicja klasy samodzielnej w pythonie

class Plan(SiloBase): 
    cost = DataField(int) 
    start = DataField(System.DateTime) 
    name = DataField(str) 
    items = DataCollection(int) 
    subPlan = ReferenceField(Plan) 

Mam metaklasa który odczytuje te informacje i wykonuje pewne konfiguracji, a klasa bazowa realizuje pewne wspólne oszczędności rzeczy. Chciałbym móc tworzyć rekursywne definicje takie jak to, ale do tej pory w moim eksperymentowaniu nie byłem w stanie uzyskać pożądanego efektu, zwykle z powodu błędu "Plan nie jest zdefiniowany". Rozumiem, co się dzieje, nazwa klasy nie jest w zasięgu wewnątrz klasy.

Odpowiedz

8

Mam metaklasa który odczytuje te informacje i wykonuje kilka konfiguracji

Większość ram, które używają metaclasses zapewnić sposób rozwiązać ten problem. Na przykład, Django:

subplan = ForeignKey('self') 

Google App Engine:

subplan = SelfReferenceProperty() 

Problem z rozwiązań takich jak sklejaniu dodatkową właściwość na później lub za pomocą __new__ jest, że większość metaclasses ORM oczekiwać właściwości klasy istnieć w momencie, gdy klasa jest tworzona.

+1

Wspaniale, że wspomniałeś także o Google App Engine! +1 –

+1

W Google App Engine - DB ma to, ale NDB tego nie robi. Aby zobaczyć, jak to zrobić w NDB, spójrz tutaj: http://stackoverflow.com/questions/3531936/selfreferenceproperty-question – Brad

22

Spróbuj tego:

class Plan(SiloBase): 
    cost = DataField(int) 
    start = DataField(System.DateTime) 
    name = DataField(str) 
    items = DataCollection(int) 

Plan.subPlan = ReferenceField(Plan) 

LUB użyć __new__ takiego:

class Plan(SiloBase): 

    def __new__(cls, *args, **kwargs): 
     cls.cost = DataField(int) 
     cls.start = DataField(System.DateTime) 
     cls.name = DataField(str) 
     cls.items = DataCollection(int) 
     cls.subPlan = ReferenceField(cls) 
     return object.__new__(cls, *args, **kwargs) 
+0

Niesamowite, to robi dokładnie to, czego chcę, a nie jest to hałaśliwy hack. wciąż próbuję zawinąć głowę wokół tej całej dynamicznej rzeczy, haha ​​ – pedlar

0

Nie, nie mogę tego zrobić. Pomyśl o tym, co by się stało, gdybyś to zrobił:

OtherPlan = Plan 
other_plan = OtherPlan() 

Na instancji z other_plan, jaka jest nazwa klasy?

W każdym razie, tego rodzaju rzeczy najlepiej zrobić w metodzie __new__, która pobiera parametr cls odnoszący się do klasy.

1

rozumiem, co się dzieje, nazwa klasy nie jest w zakresie wewnątrz klasy.

Niezupełnie. Nazwa klasy nie jest jeszcze zdefiniowana podczas definiowania jej zawartości (np. Zakresu).

Powiązane problemy