Python 的描述器Descriptors

原创 社长  2019-08-24 14:21:33  阅读 47 次 评论 0 条
重庆专业seo
摘要:

描述器的表现—————————————————————————用到3个魔术方法: __get__()\__set__()\__delete__()方法签名:object.__get__(self, instance, owner)object.__set__(self, instance, value)object.__delete__(self, instance)self 指当前实例,调用者instance是owner的实例owner是属性的所属的类描述器定义————————————————

描述器的表现

—————————————————————————

用到3个魔术方法: __get__()\__set__()\__delete__()

方法签名:

object.__get__(self, instance, owner)

object.__set__(self, instance, value)

object.__delete__(self, instance)

self 指当前实例,调用者

instance是owner的实例

owner是属性的所属的类

Python 的描述器Descriptors

描述器定义

——————————————————————————

Python中,一个类实现了__get__()\__set__()\__delete__()中的任一种方法,就是描述器。

非数据描述符:仅实现__get__

数据描述符:实现__get__ \ __set__

如果一个类的类属性设置为描述器,它被称为owner属主

属性的访问顺序

——————————————————————————

class A:

def __init__(self):

self.a1 = ‘a1’

print(‘A init’)

def __get__(self, instance, owner):

print(“A.__get__{} {} {}”.format(self, instance, owner))

return self

def __set__(self, instance, value):

print(“A.__set__{} {} {}”.format(self , instance , value))

self.data = value

def __delete__(self, instance):

print(“A.__delete__{} {}”.format(self , instance))

del self

class B:

x = A()

def __init__(self):

print(‘B init’)

self.y = ‘y1’

self.x = ‘b.x’ #增加实例属性

print(‘-‘*20)

print(B.x)

print(B.x.a1)

print(‘=’*20)

b = B()

print(b.x)

print(b.x.data)

print(b.__dict__)

b.x.a1 = 200

print(b.x.__dict__)

print(b.__dict__)

del b.x

print(b.x)

print(b.x.a1)

print(b.__dict__)

print(‘+’*20)

b.x = 300 #调用数据数据描述符的__set__方法,或非数据描述器的实例覆盖

B.x = 600 #赋值即定义,覆盖类属性

print(b.x)

print(b.__dict__)

print(B.__dict__)

属性查找顺序:

实例的__dict__优先于非数据描述符

数据描述符优先于实例的__dict__ (属性查找变成了描述器的__set__)

Python中的描述器应用

————————————————————————————

staticmethod() 和 classmethod()是非数据描述器。实例可以重新定义和覆盖方法。

property()是数据描述符。实例不能覆盖属性的行为。

class staticmethod:

def __init__(self, fn):

self._fn = fn

print(‘1 init’)

def __get__(self, instance, owner):

print(“1.__get__{} {} {}”.format(self, instance, owner))

return self._fn

class classmethod:

def __init__(self , fn):

self._fn = fn

print(‘2 init’)

def __get__(self, instance , owner):

from functools import partial

print(“2.__get__{} {} {}”.format(self , instance , owner))

return partial(self._fn, owner)

class property:

def __init__(self, fn):

self._fn = fn

self.setfn = None

print(‘3 init’)

def __get__(self, instance, owner):

print(“3.__get__{} {} {}”.format(self , instance , owner))

return self._fn(instance)

def __set__(self, instance, value):

print(“3.__set__{} {} {}”.format(self , instance , value))

self.setfn(instance,value)

# def getter(self):

# return self.__get__

def setter(self,fn):

self.setfn = fn

return self

class B:

@staticmethod # add = staticmethod(add) -> add

def add(x, y):

return x + y

@classmethod # add = staticmethod(add) -> add

def add(cls, x, y):

return x + y

@property # x = property(x) -> x

def x(self):

return self._x

@x.setter # x = x.setter(x) -> x

def x(self, value):

self._x = value

def __init__(self):

self._x = 6

b = B()

# print(b.add(3, 5))

# print(b.__dict__)

# print(B.__dict__)

print(b.x)

b.x = 10

print(b.x)


本文地址:http://dxf6.com/post/386.html
版权声明:本文为原创文章,版权归 社长 所有,欢迎分享本文,转载请保留出处!
重庆专业seo
数据湾

发表评论


表情

还没有留言,还不快点抢沙发?