【问题标题】:What is a property object?什么是属性对象?
【发布时间】:2015-07-14 06:50:37
【问题描述】:

我不是 python 新手,但我有一个非常基本的问题。

我在玩python,发现有type属性

>>> property
<type 'property'>

但我只听说过函数上下文中的属性。

>>> a = property()
<property object at 0x0246C090>

但是属性对象呢?他们有什么用?属性方法不是很直观,也不是很有启发性

>>> dir(a)
['__class__', '__delattr__', '__delete__', '__doc__', '__format__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__set__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'deleter', 'fdel', 'fget', 'fset', 'getter', 'setter']

感谢您的关注!

【问题讨论】:

    标签: python python-2.7 properties


    【解决方案1】:

    property 对象实际上是您认为的属性。考虑这个例子:

    class Foo(object):
        def __init__(self):
            self._bar = 0
    
        @property
        def bar(self):
            return self._bar + 5
    

    Foo.bar 是一个具有__get__ 方法的属性对象。当你写类似的东西时

    x = Foo()
    print(x.bar)
    

    x.bar 的查找发现type(x).bar 有一个__get__ 方法,因此属性查找变得等价于

    type(x).bar.__get__(x, type(x))
    

    产生值x._bar + 5

    使用property 作为装饰器在某种程度上掩盖了barproperty 对象的事实。一个等价的定义是

    class Foo(object):
         def __init__(self):
             self._bar = 0
    
         bar = property(lambda self: self._bar + 5)
    

    这更明确地表明您正在使用给定的lambda 表达式创建一个property 对象作为该属性的getter,并将该对象绑定到类属性bar

    property 类(以及实例方法、类方法和静态方法)是 Python 通用描述符协议的特定应用,它使用 __get____set__ 和/或定义类属性的行为__del__ 方法。

    【讨论】:

      【解决方案2】:
      class MyClass:
          def __init__(self,*costs):
              self.costs = costs
          def item_cost(self):
              return sum(self.costs)
      

      现在可以了

      MyClass(1,2,3,4).item_cost() #prints 10
      

      但我们可以将其设为属性

      class MyClass:
          def __init__(self,*costs):
              self.costs = costs
          @property
          def item_cost(self):
              return sum(self.costs)
      

      现在我们可以将它作为一个简单的变量来访问

      MyClass(1,2,3,4).item_cost
      

      你也可以为这个值创建一个设置器

        ...
         @item_cost.setter
         def set_item_cost(self,value):
               pass #do something with value
        ...
       MyClass(1,2,3,4).item_cost = "yellow"
      

      总的来说,我发现它们是一种反模式......但有些人喜欢它们

      (旁注,您也可以将其作为常规函数而不是装饰器 MyClass.item_cost_prop = property(MyClass.item_cost) 使用它作为属性)

      【讨论】:

        【解决方案3】:

        属性是一个包含getter和setter方法的属性对象。

        【讨论】:

        • 基本上,使用该符号您可以避免使用装饰符号。
        • 这并不能解释属性的实际作用。
        猜你喜欢
        • 2015-01-18
        • 2018-04-30
        • 2019-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2016-10-27
        相关资源
        最近更新 更多