• Python property,属性


    參考资料

    http://www.ibm.com/developerworks/library/os-pythondescriptors/

      

      

    顾名思义,property用于生成一个属性。通过操作这个属性。能够映射为对某些函数的操作,类似于C#。

      

    形式为

    pvar = propery(get_func, set_func, del_fun, doc_func);

    在get。set,del,doc的时候分别调用对应的函数;

      

    尝试这样定义

    >>> aa = property(lambda: "hello", lambda x: print(x))

    >>> aa

    <property object at 0x7fdcd9ecf9a8>

    >>> aa = 1

      

    看来property仅仅有在class中才有意义(看后文)

    >>> class Test:

    ... aa = property(lambda self: "hello", lambda self,x: print(x))

    ...

    >>> t = Test()

    >>> t.aa

    'hello'

    >>> t.aa = (1,2,2)

    (1, 2, 2)

      

      

    property的神奇面纱

    事实上propery并非一个真正的函数,而是一个类

    >>> type(property)

    <class 'type'>

      

    而普通的函数为

    >>> def f():

    ... pass

    ...

    >>> type(f)

    <class 'function'>

      

    property类实现了__get__, __set__, __delete__方法,这3个方法合在一起,就定义了描写叙述符规则,实现了当中不论什么一个方法的对象就叫描写叙述符(descriptor)。描写叙述符的特殊之处在于它使怎样被訪问的。比方,程序读取一个属性时。假设该属性被绑定到实现了__get__方法的对象上。那么就会调用__get__方法(返回其结果),而不是简单的返回该对象。

    class Something:

    ... def __get__(self, instance, owner):

    ... print(instance)

    ... print(owner)

    ... return "__get__"

    ... def __set__(self, instance, name):

    ... print(instance)

    ... print(name)

    ... print("__set__")

      

    >>> class Holder:

    ... s = Something()

    ...

    >>> h = Holder()

    >>> h.s

    <__main__.Holder object at 0x7fdcd9ed8518>

    <class '__main__.Holder'>

    '__get__'

    >>> h.s = 3

    <__main__.Holder object at 0x7fdcd9ed8518>

    3

    __set__

      

    Something的__get__ 和 __set__方法的參数instance,相应了Something对象所所绑定的对象;能够想象。Property是通过instance调用传入当中的get, set, del, doc

      

    须要注意的是:描写叙述符必须被赋值给类属性,而不是对象实例属性,才有效

    >>> class Something:

    ... pass

    >>> setattr(Something, 'aa', property(lambda self: "hello", lambda self, x: print(x)))

    >>> t.aa

    'hello'

    >>> t.aa = 3

    3

      

    而设置在对象实例上,则无效果:

    >>> setattr(t, 'aa', property(lambda self: "hello", lambda self, x: print(x)))

    >>> setattr(Something, 'aa', None)

    >>> t.aa

    <property object at 0x7fdcd9edf4f8>

    >>> t.aa = 3

      

      

    另外,还能够通过注解(Annotation)的方式定义property

    class C(object):

    | @property

    | def x(self):

    | "I am the 'x' property."

    | return self._x

    | @x.setter

    | def x(self, value):

    | self._x = value

    | @x.deleter

    | def x(self):

    | del self._x

      

      

    http://www.ibm.com/developerworks/library/os-pythondescriptors/给了一种动态创建Property的方法

    class Person(object):

      

    def addProperty(self, attribute):

    # create local setter and getter with a particular attribute name

    getter = lambda self: self._getProperty(attribute)

    setter = lambda self, value: self._setProperty(attribute, value)

      

    # construct property attribute and add it to the class

    setattr(self.__class__, attribute, property(fget=getter,

    fset=setter,

    doc="Auto-generated method"))

      

    def _setProperty(self, attribute, value):

    print "Setting: %s = %s" %(attribute, value)

    setattr(self, '_' + attribute, value.title())

      

    def _getProperty(self, attribute):

    print "Getting: %s" %attribute

    return getattr(self, '_' + attribute)

      

  • 相关阅读:
    【分布式】SpringCloud(2)--SpringCloud分布式架构思想的理解
    【分布式】SpringCloud(1)--基于RestTemplate构建简易微服务调用框架
    【问题管理】-- MyBatis实体类的属性名和数据库列名不一致解决方法汇总
    【开发工具】-- 一文全面解析 Postman 工具
    【数据库】Redis(4)--Redis进阶Redis配置与持久化
    【数据库】Redis(3)--Redis事务、Jedis、SpringBoot整合Redis
    分享的面试问题,java学习教程
    怎么保证缓存和数据库一致性
    详解一条 SQL 的执行过程
    json字符串{"1-3": 29},{"8-": 50},{"8-": 50},返回 1-3天 29,大于8天 100
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7401015.html
Copyright © 2020-2023  润新知