Tak więc, staram się wymyślić najlepszy (najbardziej elegancki z najmniejszą ilością kodu) sposób, aby umożliwić nadpisanie określonych funkcji właściwości (np. Po prostu pobierający, po prostu ustawiający itp.) w python. Jestem fanem następującego sposobu tworzenia właściwości, ponieważ wszystkie ich metody są hermetyzowane w tym samym wciętym bloku kodu (łatwiej jest zauważyć, gdzie kończą się funkcje zajmujące się jedną właściwością i funkcje dotyczące następny rozpocząć):Zastępowanie właściwości w pythonie
@apply
def foo():
"""A foobar"""
def fget(self):
return self._foo
def fset(self, val):
self._foo = val
return property(**locals())
Jednakże, jeśli chcę dziedziczą z klasy, która określa właściwości w ten sposób, a potem, powiedzmy, przesłonić funkcję seter foo
, wydaje się trudne. Zrobiłem kilka wyszukiwania i większość odpowiedzi, które znalazłem, aby zdefiniować oddzielne funkcje w klasie bazowej (np. getFoo
i setFoo
), jawnie utworzyć z nich definicję właściwości (np. foo = property(lambda x: x.getFoo(), lambda x, y: x.setFoo(y), lambda x: x.delFoo())
), a następnie przesłonić getFoo
, setFoo
i delFoo
w razie potrzeby.
Nie podoba mi się to rozwiązanie, ponieważ oznacza to, że muszę zdefiniować lambas dla każdej właściwości, a następnie wypisać każde wywołanie funkcji (kiedy przedtem mogłem właśnie wykonać property(**locals())
). Ja także nie otrzymuję enkapsulacji, którą miałem pierwotnie.
Idealnie, co chciałbym, aby móc zrobić byłoby coś takiego:
class A(object):
def __init__(self):
self.foo = 8
@apply
def foo():
"""A foobar"""
def fget(self):
return self._foo
def fset(self, val):
self._foo = val
return property(**locals())
class ATimesTwo(A):
@some_decorator
def foo():
def fset(self, val):
self._foo = val * 2
return something
I wtedy wyjście będzie wyglądać następująco:
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
Zasadniczo ATimesTwo
dziedziczy getter funkcja od A
, ale zastępuje funkcję ustawiania. Czy ktoś wie, jak to zrobić (w sposób, który wygląda podobnie do powyższego przykładu)? Jaką funkcję powinien wyglądać some_decorator
, a co powinie zwrócić funkcja foo
?
Nie widzę sposobu, aby zrobić to, co chcesz z samym dekoratorem, ponieważ nie ma ono dostępu do obiektu, tylko do funkcji. domyślam się, że masz dekorator, który zwraca funkcję, która działa dalej, gdy metoda jest najpierw wywoływana, ale potem nadpisałeś początkowe foo. także - jak pewnie wiesz - nie używasz języka w zamierzonym stylu ... ale możesz znaleźć sposób, aby to zrobić za pomocą metaklasu. –
To podobne pytanie może być pomocne: http://stackoverflow.com/questions/237432/python-properties-and-inheritance – stderr