Czy da się tak zrobić aby "metaklasa była lazy", to znaczy, aby
wywołanie metody __new__ w MyMeta nastąpiło w wyniku świadomego
odwołania do klasy B (patrz kod niżej), czyli, np kiedy zrobię tak:
print B.myattr
print B().myattr
a nie w chwili gdy interpreter napotka już tylko samą definicję klasy
(czyli za każdym razem, niezależnie czy jej używam):
class B(A): pass
?
Z góry dzięki za odpoweidź.
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print "Metaclass"
super_new = super(MyMetal, cls).__new__
parents = [b for b in bases if isinstance(b, MyMeta)]
if not parents:
return super_new(cls, name, bases, attrs)
module = attrs.pop('__module__')
new_class = super_new(cls, name, bases, {'__module__':
module})
...
...
return new_class
class A(object):
__metaclass__ = MyMeta
class B(A):
pass
> print B.myattr
> print B().myattr
> a nie w chwili gdy interpreter napotka już tylko samą definicję klasy
> (czyli za każdym razem, niezależnie czy jej używam):
> class B(A): pass
> ?
Definicja klasy, to też jej utworzenie.
>>> class K(object): pass
jest równoznaczne z:
>>> K = type('K', (object,), {})
Metaklasa sprawia jedynie, że to się zamienia w:
>>> K = my_meta('K', (object,), {})
>
> Z góry dzięki za odpoweidź.
>
> class MyMeta(type):
>
> def __new__(cls, name, bases, attrs):
> print "Metaclass"
> super_new = super(MyMeta, cls).__new__
> parents = [b for b in bases if isinstance(b, MyMeta)]
O ile nie zadeklarujesz podklasy MyMeta z MyMeta jako jej metaklasą,
to raczej nie ma szans na spełnienie tego warunku.
> Czy da się tak zrobić aby "metaklasa była lazy", to znaczy, aby
> wywołanie metody __new__ w MyMeta nastąpiło w wyniku świadomego
> odwołania do klasy B (patrz kod niżej), czyli, np kiedy zrobię tak:
> print B.myattr
> print B().myattr
> a nie w chwili gdy interpreter napotka już tylko samą definicję klasy
> (czyli za każdym razem, niezależnie czy jej używam):
> class B(A): pass
> ?
Tak wprost się nie da.
Ale możesz w ramach lub niezależnie od Twojej metaklasy utworzyć
taki mechanizm, że z chwilą stworzenia danej klasy tak naprawdę
utworzona zostanie jedynie "pusta" klasa-wrapper, która będzie się
zachowywać tak, że dopiero z chwilą pierwszego pobrania
jakiegokolwiek jej atrybutu będzie ona tworzyć właściwą klasę.
(Jak będę miał chwilę, to naszkicuję, jak to mogłoby wyglądać).
Pytanie tylko, w czym Ci przeszkadza utworzona a niewykorzystana
klasa?
pozdr.
*j
> O ile nie zadeklarujesz podklasy MyMeta z MyMeta jako jej metaklasą,
> to raczej nie ma szans na spełnienie tego warunku.
Właśnie tylko pytanie, czy to jest takie w "stylu Pythona" i co z
działaniem takiego rozwiązania (tzn. czy można się potem spodziewać
jakiś pułapek manipulując klasą jej atrybutami i obiekatmi).
> Ale możesz w ramach lub niezależnie od Twojej metaklasy utworzyć
> taki mechanizm, że z chwilą stworzenia danej klasy tak naprawdę
> utworzona zostanie jedynie "pusta" klasa-wrapper, która będzie się
> zachowywać tak, że dopiero z chwilą pierwszego pobrania
> jakiegokolwiek jej atrybutu będzie ona tworzyć właściwą klasę.
> (Jak będę miał chwilę, to naszkicuję, jak to mogłoby wyglądać).
Też myślałem nad czymś podobnym, problem w tym, że to ładnie
wychodziło podczas tworzenia samej instacji ( B().myattr), natmiast
gdzieś się pogubiłem podczas wywołania typu B.myattr (w zasadzie to
były tylko rozważania, nie implmentowałem tego rozwiązania jeszcze)
> Pytanie tylko, w czym Ci przeszkadza utworzona a niewykorzystana
> klasa?
W cały problem nie będę wchodził bo jest dość skomplikowany (min.
wykorzystywany zew. aplikacja, która na wejściu przyjmuje klasę
określonego typu z określonymi atrybutami etc..), natmoast wartości
atrybutów tejże klasy są wynikiem dość kosztownych obliczeń. Dlatego
jeśli bedę miał 100 klas, a wykorzystam tylko 10 (może tak się
zdarzyć) to 90 razy wykonam zbędne obliczenia. Natmoast wołanie na
każdej instacji np. funkcji obliczającej mi te parametry na żądanie,
typu: obj.clc_param() nie wchodzi w grę.. Korzystanie z klasy ma się
ograniczyć do B.myattr i B().myattr (korzysta z tego automat nie
programista).
Dzięki.
Pozdrawiam.
> natomiast wartości
> atrybutów tejże klasy są wynikiem dość kosztownych obliczeń. Dlatego
A nie wystarczy, że atrybuty będą leniwie wyliczane ? Patrz @property.
Je�li tylko o to chodzi to mo�e podej�� do problemu od innej strony i
u�y� mechanizmu properties?
Wtedy de facto wywo�ywana jest metoda, kt�ra mo�e zrobi� czasoch�onne
obliczenia, ale z punktu widzenia "klienta" tej klasy wygl�da to jak
dost�p do atrybutu.
Metoda wykona si� dopiero w momencie odwo�ania do atrybutu wi�c
"nieu�ywane" obiekty oblicze� nie wykonaj�.
Nnie wiem czy to jest to o co Ci chodzi bo Tw�j opis jest dosy�
enigmatyczny ;).
Pzdr J.