将继承的 属性 方法包装在子 class 中的方法中时工作
Getting inherited property methods to work when wrapped inside method in child class
我正在尝试让父 class 中描述的 property/setter 方法在继承到子 class 时起作用。当我直接分配来自父 class 的呼叫时,我能够让它工作,如下所示。但在我的例子中,我需要将相同的调用包装在一个方法中,以便我可以在调用父 class 之前进行一些计算。我可以通过使用 fget 方法并将对象传递给它来使其工作,但我希望前一种方法能够工作。
我在 Whosebug 上查找了这个问题,发现了一些涉及使用 super() 的方法,我试过了,但没有用。
任何帮助让这个继承的 属性 方法在子 class 中工作的方法都值得赞赏!
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
@staticmethod
def slices():
def get_slices(self):
return self.n
def set_slices(self, n):
self.n = n
return property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
his_slices = A.slices() # <--- works well
def her_slices(self): # <--- does not work
return A.slices()
if __name__ == "__main__":
b = B(100)
# This works
print("%d slices" % b.his_slices)
# 100 slices
# This fails
print("%d slices" % b.her_slices)
# TypeError: %d format: a number is required, not method
# Can be made to work like this, but I want above to work
ss = b.her_slices()
print("%d slices" % ss.fget(b))
# 100 slices
我想你正在寻找更像这样的东西。
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
self.slices
def get_slices(self):
return self.n
def set_slices(self, n):
self.n = n
slices = property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
his_slices = A.slices # <--- works well
def her_slices(self): # <--- does not work
return self.slices
if __name__ == "__main__":
b = B(100)
# This works
print("%d slices" % b.his_slices)
# 100 slices
# This fails
print("%d slices" % b.her_slices())
# TypeError: %d format: a number is required, not method
虽然我不太确定你想做什么。
像对待任何其他继承一样对待它。如果您需要修改 child class 中常规函数的行为,您只需重新定义该函数并完全更改其内容,或者使用 super 扩展它并进一步修改它。
在 setters/getters 的情况下,你会做同样的事情...... redefine/extend 他们。
在你的情况下,情况有点不同,因为正如其中一位评论者指出的那样,slices
实际上是 staticmethod
,returns 是 property
,并且不是 属性 属性本身。因此,您确实没有可以继承和扩展的现有命名 属性。
看看您在 __main__
中尝试做的事情,您真正想做的是在 child 中创建一个名为 his_slices
的新 属性 class 并在 getter
和 setter
中适当地调用 A.slices
。像这样
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
@staticmethod
def slices():
def get_slices(self):
print("Get", self.n)
return self.n
def set_slices(self, n):
print("Set", n)
self.n = n
return property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
@property
def his_slices(self):
return A.slices().fget(self)
@his_slices.setter
def his_slices(self, v):
value = self.n + v
print("modified n in setter", value)
A.slices().fset(self, value)
if __name__ == "__main__":
b = B(100)
# setter
b.his_slices = 101
# getter
print("%d slices" % b.his_slices)
如果 slices
确实是基础 class 中的 属性,这就是您继承和修改 getter 和 setter 的方式。也描述了here
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
def get_slices(self):
print("Get A", self.n)
return self.n
def set_slices(self, n):
print("Set A", n)
self.n = n
slices = property(get_slices, set_slices)
class B(A):
@property
def slices(self):
print("Get B", self.n)
return A.slices.fget(self)
@slices.setter
def slices(self, v):
value = self.n + v
print(".. Modifing value before Set", value)
A.slices.fset(self, value)
if __name__ == "__main__":
a = A(10)
b = B(10)
a.slices = 9
b.slices = 11
print("%d a-slices" % a.slices)
print("%d b-slices" % b.slices)
以上代码的输出:
Set A 9
Modifing value before Set 21
Set A 21
Get A 9
9 a-slices
Get B 21
Get A 21
21 b-slices
...当有疑问时,回到基础并聆听 Raymond Hettinger has to say about properties
总是有用的
我正在尝试让父 class 中描述的 property/setter 方法在继承到子 class 时起作用。当我直接分配来自父 class 的呼叫时,我能够让它工作,如下所示。但在我的例子中,我需要将相同的调用包装在一个方法中,以便我可以在调用父 class 之前进行一些计算。我可以通过使用 fget 方法并将对象传递给它来使其工作,但我希望前一种方法能够工作。
我在 Whosebug 上查找了这个问题,发现了一些涉及使用 super() 的方法,我试过了,但没有用。
任何帮助让这个继承的 属性 方法在子 class 中工作的方法都值得赞赏!
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
@staticmethod
def slices():
def get_slices(self):
return self.n
def set_slices(self, n):
self.n = n
return property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
his_slices = A.slices() # <--- works well
def her_slices(self): # <--- does not work
return A.slices()
if __name__ == "__main__":
b = B(100)
# This works
print("%d slices" % b.his_slices)
# 100 slices
# This fails
print("%d slices" % b.her_slices)
# TypeError: %d format: a number is required, not method
# Can be made to work like this, but I want above to work
ss = b.her_slices()
print("%d slices" % ss.fget(b))
# 100 slices
我想你正在寻找更像这样的东西。
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
self.slices
def get_slices(self):
return self.n
def set_slices(self, n):
self.n = n
slices = property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
his_slices = A.slices # <--- works well
def her_slices(self): # <--- does not work
return self.slices
if __name__ == "__main__":
b = B(100)
# This works
print("%d slices" % b.his_slices)
# 100 slices
# This fails
print("%d slices" % b.her_slices())
# TypeError: %d format: a number is required, not method
虽然我不太确定你想做什么。
像对待任何其他继承一样对待它。如果您需要修改 child class 中常规函数的行为,您只需重新定义该函数并完全更改其内容,或者使用 super 扩展它并进一步修改它。
在 setters/getters 的情况下,你会做同样的事情...... redefine/extend 他们。
在你的情况下,情况有点不同,因为正如其中一位评论者指出的那样,slices
实际上是 staticmethod
,returns 是 property
,并且不是 属性 属性本身。因此,您确实没有可以继承和扩展的现有命名 属性。
看看您在 __main__
中尝试做的事情,您真正想做的是在 child 中创建一个名为 his_slices
的新 属性 class 并在 getter
和 setter
中适当地调用 A.slices
。像这样
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
@staticmethod
def slices():
def get_slices(self):
print("Get", self.n)
return self.n
def set_slices(self, n):
print("Set", n)
self.n = n
return property(get_slices, set_slices)
class B(A):
def __init__(self, n):
self.n = n
@property
def his_slices(self):
return A.slices().fget(self)
@his_slices.setter
def his_slices(self, v):
value = self.n + v
print("modified n in setter", value)
A.slices().fset(self, value)
if __name__ == "__main__":
b = B(100)
# setter
b.his_slices = 101
# getter
print("%d slices" % b.his_slices)
如果 slices
确实是基础 class 中的 属性,这就是您继承和修改 getter 和 setter 的方式。也描述了here
class A(object):
""" Base Class """
def __init__(self, n):
self.n = n
def get_slices(self):
print("Get A", self.n)
return self.n
def set_slices(self, n):
print("Set A", n)
self.n = n
slices = property(get_slices, set_slices)
class B(A):
@property
def slices(self):
print("Get B", self.n)
return A.slices.fget(self)
@slices.setter
def slices(self, v):
value = self.n + v
print(".. Modifing value before Set", value)
A.slices.fset(self, value)
if __name__ == "__main__":
a = A(10)
b = B(10)
a.slices = 9
b.slices = 11
print("%d a-slices" % a.slices)
print("%d b-slices" % b.slices)
以上代码的输出:
Set A 9
Modifing value before Set 21
Set A 21
Get A 9
9 a-slices
Get B 21
Get A 21
21 b-slices
...当有疑问时,回到基础并聆听 Raymond Hettinger has to say about properties
总是有用的