简体   繁体   English

python将内置属性函数分配给列表元素

[英]python assign build-in property function to list element

I don't understand why the following code gives two different outputs 我不明白为什么下面的代码给出两个不同的输出

class foo(object):

       def myget(self):
          return 3

       goo=property(myget)

       hh1=[1,2,3]
       hh1[0]=property(myget)

       def hh(self):
         print self.goo
         print self.hh1[0]
ff=foo()
ff.hh()       

output: 输出:

 3
 <property object at 0x292a998>

Thanks 谢谢

property objects are descriptors . property对象是描述符 Descriptors only have special powers when bound to a class. 描述符仅在绑定到类时才具有特殊功能。 Otherwise, they behave exactly like any other class. 否则,它们的行为与任何其他类完全相同。 When you put the property in a list, it is not bound to the class, so it loses it's special properties. 当将该属性放在列表中时,它没有绑定到该类,因此会丢失其特殊属性。


For an example, let's look at an implementation of property written in pure python as descriptors: 例如,让我们看一下用纯python作为描述符编写property的实现:

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError, "unreadable attribute"
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError, "can't set attribute"
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError, "can't delete attribute"
        self.fdel(obj)

Notice how the second argument to __get__ , __set__ and __delete__ are obj? 注意__get____set____delete__的第二个参数是obj吗? obj is the instance of the class that the descriptor is bound to (it gets passed to the method as self if that help clarify things). obj是描述符绑定到的类的实例(如果有助于说明问题,它将作为self传递给方法)。 In order for the whole shebang to work, the descriptor must be bound to a class so that __get__ can be called and obj can be passed to it. 为了使整个shebang正常工作,必须将描述符绑定到一个类, __get__可以调用__get__并将obj传递给它。 If the descriptor isn't bound to a class, then __get__ doesn't get called and your descriptor class becomes just another class with a couple of magic methods that never get called (unless you call them explicitly). 如果描述符未绑定到类,则不会调用__get__ ,并且您的描述符类将变为具有两个永远不会被调用的魔术方法的另一个类(除非您显式调用它们)。

Maybe slightly more concretely, when you do: 在执行以下操作时,也许更具体一点:

a = instance.my_descriptor

this calls my_descriptor.__get__(instance) and correspondingly: 这将调用my_descriptor.__get__(instance)并相应地:

instance.my_descriptor = a

calls my_descriptor.__set__(instance,a) 调用my_descriptor.__set__(instance,a)

However, if my_descriptor isn't bound to a class, then it behaves just like any other class (object) which explains what you're seeing. 但是,如果my_descriptor未绑定到类,则它的行为就像解释您所看到的内容的任何其他类(对象)一样。

i think it may be related to dict . 我认为这可能与字典有关。 descriptor (property) only respond to attributes inside object or class dict . 描述符(属性)仅响应object或class dict中的属性。 Both hh1[] and goo are in foo. hh1 []和goo都在foo中。 dict . 字典 but hh1[0] is not, therefore, descriptor doesnt work in hh1[0]. 但是hh1 [0]无效,因此描述符在hh1 [0]中不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM