微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以在Python中使用参数调用getter和setter属性?

如何解决是否可以在Python中使用参数调用getter和setter属性?

可能无法按照我想要的方式完成。我正在用python制作class Temperature

我想设置一个名为temperature属性,并以Kevin,Celsius或Fahrenheit等不同尺度设置或检索其值。

设置温度:

T = Temperature() 
T.temperature = 20                # Set temperature to 20ºC
T.temperature('Fahrenheit') = 68  # Set temperature to 68ºF
T.temperature('Kelvin') = 305     # Set temperature to 305K

获取温度:

t = T.temperature                 # retrieves temperature in Celsius
t = T.temperature('Fahrenheit')   # retrieves temperature in Fahrenheit
t = T.temperature('Kelvin')       # retrieves temperature in Kelvin

我有这个代码。首先,我尝试使用@property装饰器,但无法正常工作。然后,我决定使用x=property(x_get,x_set)

转向传统语法
class Temperature:
    def __init__(self,temperature:float = 0,scale:str = "Celsius"):
        # All temperatures will be stored as KELVIN
        self._temperature = None
        self.set_temperature(temperature,scale)

    def get_temperature(self,scale: str = "Celsius"):
        converter = {
            "Celsius": self._temperature - 273.15,"Fahrenheit": ((self._temperature - 273.15) * 1.8) + 32,"Kelvin": self._temperature
        }
        value = converter.get(scale)

        return value

    def set_temperature(self,value: float,scale: str = "Celsius"):
        converter = {
            "Celsius": value + 273.15,"Fahrenheit": (value - 32) / 1.8 + 273.15,"Kelvin": value
        }

        self._temperature = converter.get(scale)

        if self._temperature < 0 :
            self._temperature = None
            raise ValueError("Temperature below 0 Kelvin is not possible")

    temperature = property(get_temperature,set_temperature)

但是我不能使用建议的语法;尽管使用传统语法似乎是一个方法

在不带任何参数的情况下调用属性temperature或直接获取和设置带有参数的方法时,它可以工作:

>>> T = Temperature(20) # Initialize
>>> T.temperature       # Getter
20.0

>>> T.temperature=30    # Setter
>>> T.temperature       # Getter
30.0

如果我直接拨打get_temperatureset_temperature

>>> T.get_temperature("Fahrenheit")
86.0

但是,如果我使用参数调用getter或setter属性,则会引发错误

T.temperature("Fahrenheit")
Traceback (most recent call last):
  File "<input>",line 1,in <module>
TypeError: 'float' object is not callable

T.temperature("Kelvin") = 301.15
  File "<input>",line 1
SyntaxError: can't assign to function call


T.temperature = 68,'Fahrenheit'
Traceback (most recent call last):
  File "<input>",in <module>
  File "<input>",line 19,in set_temperature
TypeError: can only concatenate tuple (not "float") to tuple

解决方法

我认为不需要getter和setter,也不需要pythonic ...通过使用getter和setter,您可以将类的属性设为私有,以保护它们免受其他代码的侵害。提供这种保护的Python方法实际上是通过公开引入属性。

以psuedo-java方式设计类,您可以执行以下操作:

class temperature:

    def __init__(self.temp):
        self.__temp = temp
    
    def get_temp(self): 
        return self.__temp
   
    def set_temp(self,temp):
        self.__temp = temp

并要访问数据,请执行以下操作

>>>temp1 = temperature(135)
>>>temp1.set_temp(14)
>>>temp1.get_temp()
14

但是,设计此类的一种更加Python化的方法是没有getter和setter并使用public属性。

class temperature: 

    def __init__(self,temp): 
        self.temp = temp

现在您无需使用getter或setter即可访问相同的属性

>>>temp1 = temperature(14)
>>>temp1.temp
14

即使数据不一定以这种方式封装……也不一定如此。

我意识到这不能解决您对这三个温度范围的担忧,但是可以通过将输入温度指定为某个单位然后使用转换等轻松地解决这个问题。

编辑

来自@Carlo的评论

可以在下面完成pythonic温度类别的操作,假设您指定了开尔文的输入温度单位,否则需要将该类别扩展为包括法氏温度和摄氏温度输入

class temperature():

    def __init__(self,temp,unit):
        self.temp = temp
        self.unit = unit

        if self.unit == 'K':
            self.temp_k = self.temp
            self.temp_c = self.temp_k + 273
            self.temp_f = (self.temp_k + 273)*(9/5)+32
        else:
            raise TypeError("only kelvin accepted as input temperature")


if __name__ == '__main__':

    temp1 = temperature(14,'K')
    temp2 = temperature(14,'C')  # will raise error

访问temp1对象的温度值然后变得简单

>>> temp1.temp_k
14
>>> temp1.temp_c
287
>>> temp1.temp_f
548.6

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。