描述符
定义
- 一个描述符是一个有“绑定行为”的对象属性(object attribute),它的访问控制会被描述器协议方法重写。
- 任何定义了 __get__, __set__ 或者 __delete__ 任一方法的类称为描述符类,其实例对象便是一个描述符,这些方法称为描述符协议。
- 同时定义了 __get__ 和 __set__ 的描述符称为 数据描述符(data descriptor);仅定义了 __get__ 的称为 非数据描述符(non-data descriptor) 。
- 两者区别在于:如果 obj.__dict__ 中有与描述符同名的属性,若描述符是数据描述符,则优先调用描述符,若是非数据描述符,则优先使用 obj.__dict__ 中属性。
- 当对一个实例属性进行访问时,Python 1、类属性,2、数据描述符,3、实例属性,4、非数据描述符,5、__getattr__()顺序进行查找,如果查找到目标属性并发现是一个描述符,Python 会调用描述符协议来改变默认的控制行为。
- 描述符是 @property,@classmethod,@staticmethod 和 super 的底层实现机制。
描述符方法
1 | __get__(self, instance, owner) |
1. 使用类方法创建描述符
1 | class Descriptor(object): |
2. 使用属性类型创建描述符
1 | class Person(object): |
3. 使用属性修饰符(proprty)创建描述符
1 | class Person(object): |
staticMethod 原理
@staticmethod : when this method is called, we don’t pass an instance of the class to it (as we normally do with methods). This means you can put a function inside a class but you can’t access the instance of that class (this is useful when your method does not use the instance).1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class StaticMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
return self.f
class E(object):
@StaticMethod
def f( x):
return x
print(E.f('staticMethod Test'))
ee = E()
print(ee.f('ee static'))
classmethod 原理
A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom.
A class method can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class. If a class method is called for a derived class, the derived class object is passed as the implied first argument.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class ClassMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, owner=None):
if owner is None:
owner = type(obj)
def newfunc(*args):
return self.f(owner, *args)
return newfunc
class E(object):
name = 'name'
@ClassMethod
def f(cls,x):
return x + cls.name
print(E.f('classMethod Test'))
参考:
Python 描述符简介
Python 描述符(Descriptor) 附实例
【案例讲解】Python为什么要使用描述符?
python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
python装饰器、描述符模拟源码实现