Python 3.x 如何根据内部状态在两组属性值之间切换?
我有一个班级,里面有一些科学数据。根据内部状态,此类的值可以显示为规范化(即无单位)或非规范化。值始终存储为规范化,但如果对象设置为非规范化状态,则用户可访问的属性(和方法)将给出非规范化值。这样,类显示为非规范化,而不需要复制存储的值 现在我使用getter实现了这个。虽然它可以工作,但它提供了很多重复的结构,我想知道是否有一种更具python风格的方式来管理它,而不会使事情过于复杂 我这样做对吗?是否有一种更优雅的方式以类似的方式在两组数据之间切换?Python 3.x 如何根据内部状态在两组属性值之间切换?,python-3.x,class,properties,state,getter,Python 3.x,Class,Properties,State,Getter,我有一个班级,里面有一些科学数据。根据内部状态,此类的值可以显示为规范化(即无单位)或非规范化。值始终存储为规范化,但如果对象设置为非规范化状态,则用户可访问的属性(和方法)将给出非规范化值。这样,类显示为非规范化,而不需要复制存储的值 现在我使用getter实现了这个。虽然它可以工作,但它提供了很多重复的结构,我想知道是否有一种更具python风格的方式来管理它,而不会使事情过于复杂 我这样做对吗?是否有一种更优雅的方式以类似的方式在两组数据之间切换? class CoolPhysicsDat
class CoolPhysicsData(object):
def __init__(self, lambda0, *args, normed=False):
self.lambda0 = lambda0 # some normalization factor (wavelength of some wave)
self.normalized = normed # user can change this state as he pleases
self._normed_tmin, self._normed_tmax, self._normed_r = self.calculate_stuffs(*args)
...
@property
def tmin(self):
if self.normalized:
return self._normed_tmin
else:
return denormalize(self.lambda0, self._normed_tmin, unit_type="time")
@property
def tmax(self):
if self.normalized:
return self._normed_tmax
else:
return denormalize(self.lambda0, self._normed_tmax, unit_type="time")
@property
def r(self):
if self.normalized:
return self._normed_r
else:
return denormalize(self.lambda0, self._normed_r, unit_type="len")
... # about 15 getters alike these
一种方法是避免使用属性,并实现
\uuuu getattr\uuuuuuu
、\uuuu setattr\uuuuuuuu
和\uuuuu delattr\uuuuuuuu
。由于您需要知道要反规范化的数量,所以实在无法逃避定义:这些定义必须在某个地方手工编码。我会这样做:
类CoolPhysicasData:
def_get_normalization_参数(self,value):
#设置单个属性的反规范化方式。。
参数={
#“属性名称”:(标准系数、标准值、单位类型)
“tmin”:(self.lambda0,self.\u normed\u tmin,“time”),
“tmax”:(self.lambda0,self.\u normed\u tmax,'时间'),
“r”:(self.lambda0,self.\u normed\u r,'len'),
}
返回参数[值]
我将实现如下内容:
。。。
def u_getattr __(自身,值):
#提取所需的参数
范数因子,范数值,单位类型=self.\u获取规格化参数(f'{value}')
如果自我规范:
返回赋范值
其他:
返回self.denormalize(标准系数、标准值、单位类型)
...
请注意,您可能还需要编写\uuuuu setattr\uuuuuu
和\uuuuuu delattr\uuuuuu
补充一点:可能对你有用。我不确定您的
\uuu init\uuu
函数中的*args
是否是确切的签名,或者您只是为了示例而简化了签名。如果您有已知的参数(没有vararg),则可以轻松地将其转换为数据类
从数据类导入数据类,字段
@数据类
类别CoolPhysicasData:
lambda0:浮动
normed:bool=字段(默认值=False)
定义后初始化(自):
#为简单起见,设置一些测试值
#当然,您可以在此处运行自定义计算。。
自标定时间=1
自标定的tmax=2
自我规范化\u r=3
def u_getattr __(自身,值):
范数因子,范数值,单位类型=self.\u获取规格化参数(f'{value}')
如果自我规范:
返回赋范值
其他:
返回self.denormalize(标准系数、标准值、单位类型)
#您可能还需要实现以下方法:
#定义设置属性(自身、名称、值):
##这里是您的自定义逻辑
# ...
#def _udelattr _;(self,name):
##这里是您的自定义逻辑
# ...
def非规范化(自身、v1、v2、v3):
#只是为了简单起见
返回5
def_get_normalization_参数(self,value):
#设置单个属性应如何反规范化。。
参数={
#“属性名称”:(标准系数、标准值、单位类型)
“tmin”:(self.lambda0,self.\u normed\u tmin,“time”),
“tmax”:(self.lambda0,self.\u normed\u tmax,'时间'),
“r”:(self.lambda0,self.\u normed\u r,'len'),
}
返回参数[值]
它更像蟒蛇吗?由你来决定。这当然会减少一些重复,但会引入更多的复杂性,而且——在我看来——更容易出现bug。回答得好!这对我来说不太合适,因为实际的类要复杂得多——但这是解决我在问题中提出的问题的好方法。