🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
6 messages
6 total messages Started by pr Sun, 03 Jan 2010 22:40
Metaklasy w Pythonie
#27125
Author: pr
Date: Sun, 03 Jan 2010 22:40
37 lines
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
#27126
Author: Łukasz Rekucki
Date: Mon, 04 Jan 2010 02:23
49 lines
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
#27130
Author: Jan Kaliszewski
Date: Mon, 04 Jan 2010 03:04
26 lines
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
#27127
Author: pr
Date: Mon, 04 Jan 2010 12:03
37 lines
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
#27128
Author: Łukasz Rekucki
Date: Mon, 04 Jan 2010 12:24
20 lines
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
#27129
Author: zbrodel
Date: Mon, 04 Jan 2010 12:48
26 lines
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