Python 3 здесь, на всякий случай, если это важно.
Я пытаюсь правильно понять, как реализовать наследование, когда используется @property
, и я уже искал StackOverflow и прочитал около 20 похожих вопросов, но безрезультатно, потому что проблемы, которые они пытаются решить, немного отличаются. Это код, который я использую для тестирования:
class Example:
def __init__(self):
self.__data = None
@property
def data(self):
return self.__data
@data.setter
def data(self, data):
self.__data = data
class Example2(Example):
def __init__(self):
super().__init__()
@property
def data(self):
return super().data # Works!
@data.setter
def data(self, data):
data = '2' + data
#Example.data = data # Works, but I want to avoid using the parent name explicitly
#super().data = data # Raises AttributeError: 'super' object has no attribute 'data'
#super().data.fset(self, data) # Raises AttributeError: 'NoneType' object has no attribute 'fset'
#super(self.__class__, self.__class__).data = data # Raises AttributeError: 'super' object has no attribute 'data'
super(self.__class__, self.__class__).data.fset(self, data) # Works!
a = Example2()
a.data = 'element a'
print(a.data)
Чего я не могу понять, так это почему super().data
работает в Example2
геттере, а не в сеттере. В смысле, почему в сеттере нужен метод с привязкой к классу, а в геттере работает метод с привязкой к экземпляру?
Может ли кто-нибудь указать мне объяснение или объяснить, почему я получаю AttributeError
в трех из пяти различных вызовов, которые я тестирую?
Да, я знаю, я мог бы использовать Example.data
в сеттере, но это не нужно в геттере, и а) я бы предпочел не использовать явно имя родительского класса, если это возможно, и б) я не понимаю асимметрии между геттером и сеттером .
self.__class__
в вызовахsuper()
, см. при вызове super() в производном классе, могу ли я передать self.__class__? а> - person Martijn Pieters   schedule 09.02.2016super()
создает прокси для класса, а доступ к имени свойства в классе возвращает исходный объект свойства. Таким образом,super(Example2, Example2).data
возвращает исходное свойство, поэтому вы можете получить доступ к.fset
. Или вы можете связать свойство сsuper(Example2, Example2).__set__(self, new_value)
. - person Martijn Pieters   schedule 09.02.2016@CLASS_NAME.var.setter
в качестве декоратора, используяproperty()
и т. д. Я сомневался, почему один синтаксис работал на сеттере, а другой синтаксис не работал. 'т. Благодаря вашему объяснению, теперь я знаю, почему (более или менее), и оказывается, что мне нужно больше изучать свойства. - person Raúl Núñez de Arenas Coronado   schedule 09.02.2016