Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何根据内部状态在两组属性值之间切换?_Python 3.x_Class_Properties_State_Getter - Fatal编程技术网

Python 3.x 如何根据内部状态在两组属性值之间切换?

Python 3.x 如何根据内部状态在两组属性值之间切换?,python-3.x,class,properties,state,getter,Python 3.x,Class,Properties,State,Getter,我有一个班级,里面有一些科学数据。根据内部状态,此类的值可以显示为规范化(即无单位)或非规范化。值始终存储为规范化,但如果对象设置为非规范化状态,则用户可访问的属性(和方法)将给出非规范化值。这样,类显示为非规范化,而不需要复制存储的值 现在我使用getter实现了这个。虽然它可以工作,但它提供了很多重复的结构,我想知道是否有一种更具python风格的方式来管理它,而不会使事情过于复杂 我这样做对吗?是否有一种更优雅的方式以类似的方式在两组数据之间切换? class CoolPhysicsDat

我有一个班级,里面有一些科学数据。根据内部状态,此类的值可以显示为规范化(即无单位)或非规范化。值始终存储为规范化,但如果对象设置为非规范化状态,则用户可访问的属性(和方法)将给出非规范化值。这样,类显示为非规范化,而不需要复制存储的值

现在我使用getter实现了这个。虽然它可以工作,但它提供了很多重复的结构,我想知道是否有一种更具python风格的方式来管理它,而不会使事情过于复杂

我这样做对吗?是否有一种更优雅的方式以类似的方式在两组数据之间切换?

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。

回答得好!这对我来说不太合适,因为实际的类要复杂得多——但这是解决我在问题中提出的问题的好方法。