🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
4 messages
4 total messages Started by Waldek M. Tue, 05 Apr 2011 06:14
Kontrola typów i wartości dla własności
#27996
Author: Waldek M.
Date: Tue, 05 Apr 2011 06:14
35 lines
1995 bytes
Cześć,

Mam pytanie odnośnie własności (właściwości? jak by tu dobrze przetłumaczyć
'property'?) w Pythonie (używam 3.2).
Zbudowałem sobie klasę z własnością "foo", w sposób następujący:
class bar:
    def __init__(self):
        self._foo = [1,2,3,4]
    @property
    def foo(self):
        print("Getter")
        return self._foo
    @foo.setter
    def foo(self, value):
        print("Setter")
        self._foo = value

Chciałbym wprowadzić kontrolę rozmiaru tej tablicy/listy, jak i wkładanych
do niej wartości.

b = bar()
b.foo = [2,4,5,1] # tutaj mogę wprowadzić kontrolę za pomocą settera
b.foo[1] = "zasmażka" # tutaj już jest problem

Domyślam się, że w tej drugiej opcji wołany jest raczej getter,
zwracający referencję do tablicy, w której jest ustawiana stosowna wartość.

Czy można w jakiś sposób kontrolować przypadek nr 2, a jeśli tak,
to w jaki? Myślałem o użyciu jakiegoś własnego typu zamiast
listy i kontrolowanie typów na jej poziomie, ale to spory 'overkill'.

Wszelkie konstruktywne pomysły i linki mile widziane.

Pozdrawiam,
Waldek
Re: Kontrola typów i wartości dla własności
#27997
Author: Rob Wolfe
Date: Tue, 05 Apr 2011 18:50
54 lines
2983 bytes
"Waldek M." <wm@localhost.localdomain> writes:

> Cześć,
>
> Mam pytanie odnośnie własności (właściwości? jak by tu dobrze przetłumaczyć
> 'property'?) w Pythonie (używam 3.2).

Wolę "właściwość", ale nie potrafię tego uzasadnić. ;)

> Zbudowałem sobie klasę z własnością "foo", w sposób następujący:
> class bar:
>     def __init__(self):
>         self._foo = [1,2,3,4]
>     @property
>     def foo(self):
>         print("Getter")
>         return self._foo
>     @foo.setter
>     def foo(self, value):
>         print("Setter")
>         self._foo = value
>
> Chciałbym wprowadzić kontrolę rozmiaru tej tablicy/listy, jak i wkładanych
> do niej wartości.
>
> b = bar()
> b.foo = [2,4,5,1] # tutaj mogę wprowadzić kontrolę za pomocą settera
> b.foo[1] = "zasmażka" # tutaj już jest problem
>
> Domyślam się, że w tej drugiej opcji wołany jest raczej getter,
> zwracający referencję do tablicy, w której jest ustawiana stosowna wartość.
>
> Czy można w jakiś sposób kontrolować przypadek nr 2, a jeśli tak,
> to w jaki? Myślałem o użyciu jakiegoś własnego typu zamiast
> listy i kontrolowanie typów na jej poziomie, ale to spory 'overkill'.
>
> Wszelkie konstruktywne pomysły i linki mile widziane.

W takich przypadkach pierwszą opcją, którą trzeba na poważnie
rozważyć jest enkapsulacja. Udostępnianie na zewnątrz własnych
struktur danych (w tym przypadku `_foo`) jest z definicji niedobre.
Po to zdefiniowałeś `_foo` jako składową niepubliczną, aby nikt
nie miał do niej bezpośredniego dostępu.
Skoro tak to API powinno wyglądać jakoś tak:

def add_value(self, value)
def get_value(self, index)

Gdy jednak zmiana API nie wchodzi w grę (te miliony użytkowników 
na całym świecie), to w tym przypadku jedyną drogą jaką widzę
jest użycie własnego typu. Nie jest to jakiś wielki "overkill",
ale jak dla mnie niezbyt eleganckie rozwiązanie.

RW
Re: Kontrola typów i wartości dla własności
#27998
Author: Waldek M.
Date: Wed, 06 Apr 2011 05:44
29 lines
2233 bytes
Dnia Tue, 05 Apr 2011 20:50:58 +0200, Rob Wolfe napisał(a):
> W takich przypadkach pierwszą opcją, którą trzeba na poważnie
> rozważyć jest enkapsulacja. Udostępnianie na zewnątrz własnych
> struktur danych (w tym przypadku `_foo`) jest z definicji niedobre.
> Po to zdefiniowałeś `_foo` jako składową niepubliczną, aby nikt
> nie miał do niej bezpośredniego 

Setter/getter miały właśnie dołożyć mi warstwę pośredniczącą;
taki lukier składniowy, dzięki któremu dostęp byłby maksymalnie prosty
i intuicyjny, ale w praktyce na 'setterze' mógłbym kontrolować 
co i w jaki sposób dostaje się do wewnątrz obiektu.
Tyle mojej pięknej idei ;-) która, jak widzę, sprawdziłaby
się chyba tylko dla typów prostych.

> Skoro tak to API powinno wyglądać jakoś tak:
> 
> def add_value(self, value)
> def get_value(self, index)
> 
> Gdy jednak zmiana API nie wchodzi w grę (te miliony użytkowników 
> na całym świecie), to w tym przypadku jedyną drogą jaką widzę
> jest użycie własnego typu. Nie jest to jakiś wielki "overkill",
> ale jak dla mnie niezbyt eleganckie rozwiązanie.

Czyli jednak wrapper. No nic, przemyślę to jeszcze.
Gdyby komuś wpadł do głowy inny pomysł, to ja bardzo chętnie ;)

Dzięki.
Waldek
Re: Kontrola typów i wartości dla własności
#27999
Author: Adam Byrtek
Date: Mon, 11 Apr 2011 23:22
26 lines
1955 bytes
On 04/06/2011 07:44 AM, Waldek M. wrote:
> Czyli jednak wrapper. No nic, przemyślę to jeszcze.
> Gdyby komuś wpadł do głowy inny pomysł, to ja bardzo chętnie;)

Tutaj przydaje się "immutability". Zwracanie wewnętrznego obiektu przez 
getter jest bezpieczne tylko wtedy, gdy nie można zmienić jego stanu. W 
tym przypadku można użyć krotki (tuple) zamiast listy[1]. W zależności 
od potrzeb konwersję można przeprowadzić w getterze, albo przechowywać 
obiekt bezpośrednio w postaci zamrożonej. Setter z kolei przed 
modyfikacją wewnętrznej reprezentacji powinien zweryfikować niezmiennik.

Oczywiście operacje typu

   b.foo[1] = 'bar'

będzie trzeba zapisać nieco mniej wygodnie jako

   new_foo = list(b.foo)
   new_foo[1] = 'bar'
   b.foo = new_foo

Pozdrawiam,
Adam

[1] Niektórzy twierdzą, że traktowanie krotek jako zamrożonych list nie 
jest zbyt eleganckie, ale to temat na osobną dyskusję.
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