Python:尝试在更改变量时重新计算类属性

Python:尝试在更改变量时重新计算类属性,python,class,iteration,Python,Class,Iteration,我正在尝试写一个CFD解算器。我想创建一个通用流体“节点”,该节点将存储属性,并在为其属性之一(如温度或压力)指定新值时重新计算其属性。因为这涉及相变,我还希望某些属性的存在依赖于其中一个存储的变量。因此,如果材料是气体,则与液体相比,存在一些额外的性质,有些性质消失 我已经花了大约两天的时间试图找出set、get和@property的一些组合,它们可以满足我的需要,但没有用。这是我关于堆栈溢出的第一篇文章,但我想我不会有什么损失 我尝试了一些关于get、set和@properties的基本教程

我正在尝试写一个CFD解算器。我想创建一个通用流体“节点”,该节点将存储属性,并在为其属性之一(如温度或压力)指定新值时重新计算其属性。因为这涉及相变,我还希望某些属性的存在依赖于其中一个存储的变量。因此,如果材料是气体,则与液体相比,存在一些额外的性质,有些性质消失

我已经花了大约两天的时间试图找出set、get和@property的一些组合,它们可以满足我的需要,但没有用。这是我关于堆栈溢出的第一篇文章,但我想我不会有什么损失

我尝试了一些关于get、set和@properties的基本教程。我有来自前一个解算器的工作(但不是意大利面)代码

class流体:
定义初始(自身、材料、温度、压力、mdot、D_液压、流动区域):
自材料=材料
自身温度=温度#K
自身压力=压力#Pa
self.mdot=mdot#m^3/s
self.D#u液压=D#u液压#m
self.Flow_面积=Flow_面积#m^2
如果自材料在[“液体”、“燃料”、“单组元推进剂”]:
自密度=1419千克/米^3
自粘性=0.125#Kg/m*s
self.cp=759.524#J/Kg*K
self.MW=0.1268#Kg/mol
self.k=0.4#W/m*k
自燃温度=388华氏度
self.Pr=self.cp*self.粘度/self.k
如果自身材料在[“气体”,“燃烧”]:
自粘性=1.48*10**-5#Kg/m*s
self.cp=2170.9#J/Kg*K
self.MW=20.819千克/摩尔
self.k=0.3#W/m*k
self.gamma=1.218#K
自重R=445#J/Kg*K
self.Pr=1
self.T#u燃烧=1900#K
自密度=自压力/(自R*自温度)#Kg/m^3
self.c=(self.gamma*self.R*self.temperature)
self.Velocity=self.mdot/self.Flow_面积#m/s
self.Re=D_液压*(自速度)*自密度/自粘度
如果self.Re<2300:
self.Nu=3.66
elif self.Re>=2300:
self.Nu=0.023*self.Re**(4/5)*self.Pr**(0.3)
self.h=self.Nu*self.k/self.D#u液压#W/m^2*k
我希望将材料从液体改为气体,以根据存储的温度/压力/R值重新计算密度


我知道我需要像@property、set和/或get这样的东西。您可能需要这样做:

class Fluid:
    def __init__(self, material, ...):
        self._material = material
        ...

    ...

    @property
    def material(self):
        return self._material

    @material.setter
    def material_setter(self, new_material):
        # Same logic that you have right now in the __init__

将材质定义为属性&重写setter,使其运行当前在构造函数中拥有的逻辑。这也应该重新计算其他属性


注意:您也可以在不使用
@property
的情况下实现这一点,方法是重写
\uuuu setattr\uuuu
方法,并在设置的属性为“material”时重新计算。或者,您也可以这样做(更改为
self.D\u液压
):

class Fluid:
    def __init__(self, material, ...):
        self._material = material
        ...

    ...

    @property
    def material(self):
        return self._material

    @material.setter
    def material_setter(self, new_material):
        # Same logic that you have right now in the __init__

class Fluid:
    def __init__(self, material, temperature, pressure, mdot, D_hydraulic, Flow_area):
        self.material    = material
        self.temperature = temperature      # K
        self.pressure    = pressure         # Pa
        self.mdot        = mdot             # m^3/s
        self.D_hydraulic = D_hydraulic      # m
        self.Flow_area   = Flow_area        # m^2
        self.set_properties()

    def set_properties(self):
        if self.material in ["liquid", "fuel", "Monopropellant"]:
            self.density           = 1419 # Kg/m^3
            self.viscosity         = 0.125 # Kg/m*s
            self.cp                = 759.524 # J/Kg*K
            self.MW                = 0.1268 # Kg/mol
            self.k                 = 0.4 # W/m*K
            self.ignition_temp     = 388 # K
            self.Pr                = self.cp*self.viscosity/self.k

        if self.material in ["gas", "burnt"]:
            self.viscosity         = 1.48*10**-5 # Kg/m*s
            self.cp                = 2170.9 # J/Kg*K
            self.MW                = 20.819 # Kg/mol
            self.k                 = 0.3 # W/m*K
            self.gamma             = 1.218 # K
            self.R                 = 445 # J/Kg*K
            self.Pr                = 1
            self.T_combustion      = 1900 # K

            self.density           = self.pressure/(self.R*self.temperature) #Kg/m^3
            self.c                 = (self.gamma*self.R*self.temperature)

        self.Velocity = self.mdot/self.Flow_area # m/s
        self.Re = self.D_hydraulic*(self.Velocity)*self.density/self.viscosity

        if self.Re < 2300:
            self.Nu = 3.66
        elif self.Re >= 2300:
            self.Nu = 0.023*self.Re**(4/5)*self.Pr**(0.3)

        self.h = self.Nu*self.k/self.D_hydraulic #W/m^2*K
    def change_material(self, material):
        self.material=material
        self.set_properties()
X=Fluid("liquid",100,1000,1,0.0004,0.0004)

X.density
Out: 1419

X.change_material('gas')

X.density
Out: 0.02247191011235955