如何修饰parent属性的getter或setter?
How to decorate a parent property's getter or setter?
我在parentclassShape
中定义了属性area
及其getter。在 child class Square
中,我想扩展 area
的 getter 功能。我写了一些不起作用的东西:
版本 1
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
# setter of `area` could be also defined here; hence in the child
# I would like to keep `area`, only decorating its getter.
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
area = Shape.area.getter(self.dosomething())
def dosomething(self):
def new_func():
print('hello child')
Shape.area.fget(self)
return new_func
sq = Square()
当我 运行 代码时,我没有得到 'hello child':
>>> sq.area
hello parent
我上面的代码有一些明显的问题。例如,在 Square
我应该有
self.area = Shape.area.getter(self.dosomething())
而不是没有self
。然后我需要在 parent...
中定义 area
的 setter
版本 2
经过一番摆弄,我想出了下面的代码,
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
@Shape.area.getter
def area(self):
print('hello child')
Shape.area.fget(self)
sq = Square()
这次好像如我所愿:
>>> sq.area
hello child
hello parent
但是,我的 ide 告诉我 Square
中的行 def area(self):
“overrides method in Shape”。
此外,IDE在Shape.area.fget(self)
中也说,self
是一个意想不到的论点。即使代码 运行s 没有错误。
感觉版本 2 是一个 hack。为什么我的 ide 在抱怨?我以为在版本2中我没有定义一个brand-newarea
,只是装饰继承area
的fget
,不是吗?
如果你想使 child class' area
属性 的 getter 使用 parent's area
属性 并扩展它的值,在这种情况下 child 的 getter 函数应该调用 super()
来访问 parent 的属性。至于让 child 的 setter 使用 parent 的 setter,你必须访问 parent 的 setter通过 parent class' 属性:
的 fset
属性
class Shape:
def __init__(self):
self._area = 'hello parent'
@property
def area(self):
return self._area
@area.setter
def area(self, value):
self._area = value
class Square(Shape):
@property
def area(self):
return super().area + ' and child'
@area.setter
def area(self, value):
Shape.area.fset(self, 'very ' + value)
sq = Square()
print(sq.area)
sq.area = 'new parent'
print(sq.area)
这输出:
hello parent and child
very new parent and child
或者,您可以在 child class 中定义新的 getter 和 setter 方法并在它们上调用 property
:
class Square(Shape):
def area_getter(self):
return super().area + ' and child'
def area_setter(self, value):
Shape.area.fset(self, 'very ' + value)
area = property(area_getter, area_setter)
摆弄后我得出了这个解决方案:
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
@area.setter
def area(self, val):
print('parent setter')
self._area = val
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
@Shape.area.getter
def area(self):
print('hello child')
return super().area
@area.setter
def area(self, val):
print('setter in child')
Shape.area.fset(self, val) # IDE complains that val is unexpected. Why?
sq = Square()
它做了我想要的,还有一个问题:ide 抱怨 val
在 Square
的 setter 部分出乎意料(在代码中注明) .虽然这运行没有问题。在 运行 代码中删除该行中的 self
会引发错误。我不明白这一点。感觉这是一个黑客。
我认为我得出的结论是您不应该扩展父 class 的属性。
我在parentclassShape
中定义了属性area
及其getter。在 child class Square
中,我想扩展 area
的 getter 功能。我写了一些不起作用的东西:
版本 1
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
# setter of `area` could be also defined here; hence in the child
# I would like to keep `area`, only decorating its getter.
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
area = Shape.area.getter(self.dosomething())
def dosomething(self):
def new_func():
print('hello child')
Shape.area.fget(self)
return new_func
sq = Square()
当我 运行 代码时,我没有得到 'hello child':
>>> sq.area
hello parent
我上面的代码有一些明显的问题。例如,在 Square
我应该有
self.area = Shape.area.getter(self.dosomething())
而不是没有self
。然后我需要在 parent...
area
的 setter
版本 2
经过一番摆弄,我想出了下面的代码,
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
@Shape.area.getter
def area(self):
print('hello child')
Shape.area.fget(self)
sq = Square()
这次好像如我所愿:
>>> sq.area
hello child
hello parent
但是,我的 ide 告诉我 Square
中的行 def area(self):
“overrides method in Shape”。
此外,IDE在Shape.area.fget(self)
中也说,self
是一个意想不到的论点。即使代码 运行s 没有错误。
感觉版本 2 是一个 hack。为什么我的 ide 在抱怨?我以为在版本2中我没有定义一个brand-newarea
,只是装饰继承area
的fget
,不是吗?
如果你想使 child class' area
属性 的 getter 使用 parent's area
属性 并扩展它的值,在这种情况下 child 的 getter 函数应该调用 super()
来访问 parent 的属性。至于让 child 的 setter 使用 parent 的 setter,你必须访问 parent 的 setter通过 parent class' 属性:
fset
属性
class Shape:
def __init__(self):
self._area = 'hello parent'
@property
def area(self):
return self._area
@area.setter
def area(self, value):
self._area = value
class Square(Shape):
@property
def area(self):
return super().area + ' and child'
@area.setter
def area(self, value):
Shape.area.fset(self, 'very ' + value)
sq = Square()
print(sq.area)
sq.area = 'new parent'
print(sq.area)
这输出:
hello parent and child
very new parent and child
或者,您可以在 child class 中定义新的 getter 和 setter 方法并在它们上调用 property
:
class Square(Shape):
def area_getter(self):
return super().area + ' and child'
def area_setter(self, value):
Shape.area.fset(self, 'very ' + value)
area = property(area_getter, area_setter)
摆弄后我得出了这个解决方案:
class Shape:
def __init__(self):
self._area = None
@property
def area(self):
print('hello parent')
return self._area
@area.setter
def area(self, val):
print('parent setter')
self._area = val
class Square(Shape):
def __init__(self):
super(Square, self).__init__()
@Shape.area.getter
def area(self):
print('hello child')
return super().area
@area.setter
def area(self, val):
print('setter in child')
Shape.area.fset(self, val) # IDE complains that val is unexpected. Why?
sq = Square()
它做了我想要的,还有一个问题:ide 抱怨 val
在 Square
的 setter 部分出乎意料(在代码中注明) .虽然这运行没有问题。在 运行 代码中删除该行中的 self
会引发错误。我不明白这一点。感觉这是一个黑客。
我认为我得出的结论是您不应该扩展父 class 的属性。