【问题标题】:property() returns different valuesproperty() 返回不同的值
【发布时间】:2018-02-19 01:21:31
【问题描述】:

我正在努力填补我对 Python property() 理解的空白。 下面是我自己想出来的代码,理解property()

class Temperature:
    def __init__(self, temp = 10):
        self.set_temp(temp)

    def to_farenheit(self):
        return (self._temp * 1.8) + 32

    def get_temp(self):
        print "getting temperature value"
        return self._temp

    def set_temp(self, temp):
        print "setting temperature value"

        if temp < -237:
            raise ValueError("this shud be above -273")
        else:
            self._temp = temp

    temps = property(get_temp, set_temp)

我执行上面的类并执行以下操作:

>>> t = Temperature()
setting temperature value

>>> t.temps
getting temperature value
10

>>> t.temps = 13

>>> t.temps
13
>>> t.get_temp()
getting temperature value
10
>>> 

正如您在上面看到的,当我尝试通过分配t.temps = 13 来设置temp 值时,set_temp() 函数没有被调用,我期望由于property() 功能而被调用。此外,我最终得到了变量 temp 的 2 个不同值

我错过了什么?

【问题讨论】:

    标签: python class properties python-2.x


    【解决方案1】:

    使用利用descriptors for propertiesnew-style classes

    class Temperature(object):
        def __init__(self, temp=10):
            self.temps = temp
    
        def to_farenheit(self):
            return (self._temp * 1.8) + 32
    
        def get_temp(self):
            print "getting temperature value"
            return self._temp
    
        def set_temp(self, temp):
            print "setting temperature value"
    
            if temp < -237:
                raise ValueError("this shud be above -273")
            else:
                self._temp = temp
    
        temps = property(get_temp, set_temp)
    

    这为您提供了“正确”的行为。

    In [30]: t = Temperature()
    setting temperature value
    
    In [31]: t.temps
    getting temperature value
    Out[31]: 10
    
    In [32]: t.temps = 100
    setting temperature value
    
    In [33]: t.temps
    getting temperature value
    Out[33]: 100
    
    In [34]: t.__dict__
    Out[34]: {'_temp': 100}
    

    【讨论】:

      【解决方案2】:

      这仅仅是因为您使用 Python 2 并忘记了继承 object。在您的情况下,property 根本不起作用,因为它是一个老式类。

      你最好继承object

      class Temperature(object):
          ...
      

      甚至更好:使用 Python 3。Python 3 不再有旧式类,您可以省略 (object) 部分,因为它是隐式的。

      但是,当您可以使用装饰器语法时,您真的不应该定义 get_tempset_temp 函数。而且你绝对不应该直接打电话给他们。

      这会更pythonic:

      class Temperature(object):
          def __init__(self, temp = 10):
              self.temps = temp
      
          def to_farenheit(self):
              return (self._temp * 1.8) + 32
      
          @property
          def temps(self):
              print("getting temperature value")
              return self._temp
      
          @temps.setter
          def temps(self, temp):
              print("setting temperature value")
              if temp < -237:
                  raise ValueError("this shud be above -273")
              else:
                  self._temp = temp
      

      该示例适用于 Python 2 Python 3。

      【讨论】:

        【解决方案3】:

        这个问题只出现在python 2中。

        来自the docs

        类属性([fget[, fset[, fdel[, doc]]]])

        为新型类(派生自对象的类)返回一个属性属性。

        (强调我的。)

        如果您通过继承object 使Temperature 成为新样式类,则该属性将按预期工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-08
          • 2014-03-29
          • 2020-02-19
          • 1970-01-01
          • 2017-11-01
          • 1970-01-01
          相关资源
          最近更新 更多