首页 > 代码库 > Python property,属性

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", lambdaself,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)

 

  

Python property,属性