gpt4 book ai didi

python - 子类化: Is it possible to override a property with a conventional attribute?

转载 作者:行者123 更新时间:2023-12-01 07:47:45 25 4
gpt4 key购买 nike

假设我们要创建一类类,它们是总体概念的不同实现或特化。假设某些衍生属性有一个合理的默认实现。我们想把它放在基类中

class Math_Set_Base:
@property
def size(self):
return len(self.elements)

因此,在这个相当愚蠢的示例中,子类将能够自动计算其元素
class Concrete_Math_Set(Math_Set_Base):
def __init__(self,*elements):
self.elements = elements

Concrete_Math_Set(1,2,3).size
# 3

但是,如果子类不想使用此默认值怎么办?这不起作用:
import math

class Square_Integers_Below(Math_Set_Base):
def __init__(self,cap):
self.size = int(math.sqrt(cap))

Square_Integers_Below(7)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 3, in __init__
# AttributeError: can't set attribute

我意识到有很多方法可以用属性覆盖属性,但是我想避免这种情况。因为基类的目的是使它的用户尽可能地过上轻松的生活,所以不要通过强加(从子类的狭narrow角度)强加于人的繁琐访问方法来增加膨胀。

能做到吗如果不是,那么下一个最佳解决方案是什么?

最佳答案

属性是数据描述符,它优先于具有相同名称的实例属性。您可以使用唯一的__get__()方法定义非数据描述符:实例属性优先于具有相同名称的非数据描述符,请参阅the docs。这里的问题是,下面定义的non_data_property仅用于计算目的(您不能定义 setter 或删除器),但是在您的示例中似乎是这种情况。

import math

class non_data_property:
def __init__(self, fget):
self.__doc__ = fget.__doc__
self.fget = fget

def __get__(self, obj, cls):
if obj is None:
return self
return self.fget(obj)

class Math_Set_Base:
@non_data_property
def size(self, *elements):
return len(self.elements)

class Concrete_Math_Set(Math_Set_Base):
def __init__(self, *elements):
self.elements = elements


class Square_Integers_Below(Math_Set_Base):
def __init__(self, cap):
self.size = int(math.sqrt(cap))

print(Concrete_Math_Set(1, 2, 3).size) # 3
print(Square_Integers_Below(1).size) # 1
print(Square_Integers_Below(4).size) # 2
print(Square_Integers_Below(9).size) # 3

但是,这假定您有权访问基类以进行此更改。

关于python - 子类化: Is it possible to override a property with a conventional attribute?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61299553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com