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
Author: Waldek M.
Date: Tue, 05 Apr 2011 06:14
Date: Tue, 05 Apr 2011 06:14
35 lines
1995 bytes
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
Author: Rob Wolfe
Date: Tue, 05 Apr 2011 18:50
Date: Tue, 05 Apr 2011 18:50
54 lines
2983 bytes
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
Author: Waldek M.
Date: Wed, 06 Apr 2011 05:44
Date: Wed, 06 Apr 2011 05:44
29 lines
2233 bytes
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
Author: Adam Byrtek
Date: Mon, 11 Apr 2011 23:22
Date: Mon, 11 Apr 2011 23:22
26 lines
1955 bytes
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