python官方手册笔记_Python学习手册笔记——管理属性

管理属性有四种方式:

1、__getattr__和__setattr__:把未定义的属性获取和所有的属性赋值指向通用的处理器方法。

2、__getattribute__:把所有的属性获取和赋值指向Python2.6中的新式类和Python 3.0中的所有类的中的一个处理器方法

3、property内置函数,把特定属性访问定位到get和set函数,也叫做特性

4、描述符:把特定属性访问定位到具有任意get和set函数的类的实例

特性

attribute = property(fget, fset, fdel, doc)

通过property把一个内置函数的结果赋给一个类属性。向 fget 传递一个函数来拦截属性访问,给 fset 传递一个函数进行赋值,并且给 fdel传递一个函数进行属性删除; doc参数接收该属性的一个文档字符串。fget有返回值,而fset和fdel没有返回值。class Person(object):

def __init__(self, name):

self._name = name

def getName(self):

print ‘fetch...‘

return self._name

def setName(self, value):

print ‘change...‘

self._name = value

def delName(self):

print ‘remove...‘

del self._name

name = property(getName, setName, delName, "name property docs")

bob = Person(‘Bob Smith‘)

print bob.name

bob.name = ‘Robert Smith‘

print bob.name

del bob.name

print ‘-‘*20

sue = Person(‘Sue Jones‘)

print sue.name

print Person.name.__doc__

使用装饰器编写特性class Person(object):

def __init__(self, name):

self._name = name

@property

def name(self): #name=property(name)

"name property docs"

print ‘fetch...‘

return self._name

@name.setter

def name(self, value): #name=name.setter(name)

print ‘change...‘

self._name = value

@name.deleter #name=name.deleter(name)

def name(self):

print ‘remove...‘

del self._name

bob = Person(‘Bob Smith‘)

print bob.name

bob.name = ‘Robert Smith‘

print bob.name

del bob.name

print ‘-‘*20

sue = Person(‘Sue Jones‘)

print sue.name

print Person.name.__doc__

property对象也有getter、setter和deleter方法,这些方法指定相应的特性访问器方法赋值并且返回特性自身的一个副本。我们也可以使用这些方法,通过装饰常规方法来指定特性的组成部分。 getattr 部分通常由创建特性自身的行为自动填充。

描述符

从功能上讲,描述符协议允许我们把一个特定属性的get和set操作指向我们提供的一个单独类对象的方法:它们提供了一种方式来插入在访问属性的时候自动运行的代码,并且它们允许我们拦截属性删除并且为属性提供文档。描述符作为独立的类创建,并且它们就像方法函数一样分配给类属性。class Descriptor(object):

"docstring goes here"

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

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

def __delete__(self, instance): ...

带有任何这些方法的类都可以看作是描述符,并且当它们的一个实例分配给另一个类的属性的时候,它们的这些方法是特殊的——当访问属性的时候,会自动调用它们。三个方法都传递了描述符类实例( s e l f )以及描述符实例所附加的客户类的实例( instance )。__get__还传递了用于表示类的owner。instance 参数要么是访问的属性所属的实例(用于instance .attr ),要么当所访问的属性直接属于类的时候是 N o n e (用于c l a s s.a t t r )。class DescStat(object):

def __init__(self,value):

self.value=value

def __get__(self,instance,owner):

return self.value

def __set__(self,instance,value):

self.value=value

def __delete__(self,instance):

def self.value

class InstState(object):

def __get__(self, instance, owner):

print ‘InstState get‘

return instance._Y * 100

def __set__(self, instance, value):

print ‘InstState set‘

instance._Y = value

class CalcAttrs(object):

X = DescState(2)

Y = InstState()

def __init__(self):

self._Y = 3

self.Z = 4

a=CalcAttrs()

a是类CalcAttrs的实例。类CalcAttrs含有类属性X,Y,实例属性_Y,Z。X是类DescStat()的实例,类DescStat含有实例属性value。Y是类InstState的实例。InstState无自身属性。对实例a的X属性的访问、赋值会触发DescStat的__get__,__set__方法。对Y属性的相关操作会触发相应的方法,作用于实例属性_Y上。

__getattr__和__getattribute__可以拦截任何实例属性的获取,适合于委托设计模式。

避免陷入潜在的循环(递归)。__getattr__只对未定义的属性调用,可以在代码中自由地获取其他属性。而__getattribute__和__setattr__针对所有的属性,因此它们的代码在访问其他属性的时候应避免再次调用自身并触发一次递归循环。例如,在一个 __g e t a t t r i b u t e__ 方法代码内部的另一次属性获取,将会再次触发__getattribute__ ,并且代码将会循环直到内存耗尽。要解决这个问题,把获取指向一个更高的超类,而不是跳过这个层级的版本—— object类总是一个超类,并且它在这里可以很好地起作用。对于__setattr__也是如此,在一个__setattr__调用中再此进行任何属性赋值。要解决此问题,可以把属性作为实例的__dict__命名空间字典中的一个键赋值。class Person(object):

"""docstring for Person"""

def __init__(self, name):

self._name = name

def __getattr__(self,attr):

if attr==‘name‘:

print ‘fetch..‘

return self._name

else:

raise AttributeError(attr)

def __setattr__(self,attr,value):

if attr==‘name‘:

print ‘change...‘

attr=‘_name‘

self.__dict__[attr]=value

def __delattr__(self,attr):

if attr==‘name‘:

print ‘remove...‘

attr=‘_name‘

del self.__dict__[attr]

bob=Person(‘Bob‘)

print bob.name

bob.name=‘Jack‘

print bob.name

del bob.name

原文地址:http://liandesinian.blog.51cto.com/7737219/1574434

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值