Thread View: pl.comp.lang.python
6 messages
6 total messages
Started by pr
Sun, 03 Jan 2010 22:40
Metaklasy w Pythonie
Author: pr
Date: Sun, 03 Jan 2010 22:40
Date: Sun, 03 Jan 2010 22:40
37 lines
2088 bytes
2088 bytes
Witam,
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
Re: Metaklasy w Pythonie
Author: Łukasz Rekucki
Date: Mon, 04 Jan 2010 02:23
Date: Mon, 04 Jan 2010 02:23
49 lines
2888 bytes
2888 bytes
On Jan 3, 11:40 pm, pr <crico...@gmail.com> wrote:
> Witam,
>
> 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:
Do pewnego stopnia tak, tylko nie bardzo wiem po co. Coś jako to B
wstawić musisz. Zresztą są prostsze sposoby zrobienia fabryki.
> 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.
> 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
Re: Metaklasy w Pythonie
Author: Jan Kaliszewski
Date: Mon, 04 Jan 2010 03:04
Date: Mon, 04 Jan 2010 03:04
26 lines
1856 bytes
1856 bytes
2010-01-03 o 23:40 pr <cricogik@gmail.com> napisał: > 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
Re: Metaklasy w Pythonie
Author: pr
Date: Mon, 04 Jan 2010 12:03
Date: Mon, 04 Jan 2010 12:03
37 lines
3338 bytes
3338 bytes
> Definicja klasy, to też jej utworzenie.>>> class K(object): pass Tak jestem tego świadom, dlatego pytam o rozwiązanie typu lazy load :-) > 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.
Re: Metaklasy w Pythonie
Author: Łukasz Rekucki
Date: Mon, 04 Jan 2010 12:24
Date: Mon, 04 Jan 2010 12:24
20 lines
2473 bytes
2473 bytes
> 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..), Szczerze mówiąc jeszcze nie widziałem aplikacji przyjmującej klasę pythonową jako wejście. Próbowałeś użyć zwykłego obiektu ? Jeśli musi być wołalny, to w jego klasię dajesz __call__(). > 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 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.
Re: Metaklasy w Pythonie
Author: zbrodel
Date: Mon, 04 Jan 2010 12:48
Date: Mon, 04 Jan 2010 12:48
26 lines
2138 bytes
2138 bytes
pr wrote: > 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). 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.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads