python基础 —— 描述符

https://blog.csdn.net/loner_fang/article/details/80877491
https://www.jianshu.com/p/eb05770c2348
https://www.jianshu.com/p/cf8450b4b537

描述符 descriptor

  1. descriptor: 某个类,只要是内部定义了方法 get, set, delete 中的一个或多个
  2. 对于对象:object.getattribute():b.x =》 type(b).dict[‘x’].get(b, type(b));对于类:type.getattribute()将B.x转换为B.dict[‘x’].get(None, B)
  3. 通过属性访问来自动地调用Descriptor(getattribute()):如果 d 定义了方法 get() ,则 obj.d 会调用 d.get(obj)
    3.1. 覆写__getattribute__()可以阻止Descriptor的自动调用
    3.2. object.getattribute()和type.getattribute()调用__get__()的方式不同
  4. 优先级链:Data Descriptor优先级 > 实例变量 > Non-data Descriptor > getattr()

数据描述符 data descriptor

一个类,如果只定义了 get() 方法,而没有定义 set(), delete() 方法,则认为是非数据描述符; 反之,则成为数据描述符

如果实例字典(类实例中__dict__)中包含了与Data Descriptor同名的属性,那么Data Descriptor优先。如果实例字典中包含了与Non-data Descriptor同名的属性,实例字典优先。

  1. 如果attr是一个Python自动产生的属性,找到!(优先级非常高!)
  2. 查找obj.class.dict,如果attr存在并且是data descriptor,返回data descriptor的__get__方法的结果,如果没有继续在obj.__class__的父类以及祖先类中寻找data descriptor
  3. obj.dict中查找,这一步分两种情况,第一种情况是obj是一个普通实例,找到就直接返回,找不到进行下一步。第二种情况是obj是一个类,依次在obj和它的父类、祖先类的__dict__中查找,如果找到一个descriptor就返回descriptor的__get__方法的结果,否则直接返回attr。如果没有找到,进行下一步。
  4. 在**obj.class.dict**中查找,如果找到了一个descriptor(插一句:这里的descriptor一定是non-data descriptor,如果它是data descriptor,第二步就找到它了)descriptor的__get__方法的结果。如果找到一个普通属性,直接返回属性值。如果没找到,进行下一步。
  5. 很不幸,Python终于受不了。在这一步,它raise AttributeError。

属性

类属性

  1. 类属性:直接在类中创建的属性。
  2. 类属性直接绑定在类上的,可以不实例化直接通过类名调用类属性。
  3. 创建的实例都会继承自唯一的类属性。
  4. 类属性改变会影响到所有实例。
  5. 实例属性和类属性重名时,实例属性优先级高,将屏蔽掉对类属性的访问

实例的属性

属性由双下划线(__)开头,无法被外部访问。外部访问:通过实例方法。

在实例方法内部,可以访问所有实例属性

一个实例的私有属性通过“__属性名”来定义,无法被外部所访问。

函数

  1. 在类中定义的函数,第一个参数是self,指向调用该方法的实例本身。
  2. 标记@classmethod,该方法将绑定到类上,而非类的实例。
  3. 类方法的第一个参数cls传入的是类本身。在类上调用 =》 类方法无法获得任何实例变量,只能获得类的引用。

特殊属性

class

x.class = type(x)

dict

  1. x.dict :查看类(实例)的属性和方法;形式为{attr_key : attr_value}。
  2. 在__init__中,self.xxx = xxx会把变量存在实例的__dict__中,仅会在该实例中能获取到,而在方法体外声明的,会在class的__dict__中

特殊方法

new():创建实例(静态方法)

在调用__new__()方法获得实例后,会调用这个实例的__init__()方法,然后将最初传给__new__()方法的参数都传给__init__()方法。

init():初始化,相当于构造函数

创建实例时,自动调用

delattr

getattribute

setattr

hash

hash

str

魔术方法

get(self, instance, owner)

实例化后,调用对象t访问其属性x,会自动调用类的 __get__方法

set(self, instance, value)

del(self, instance)

你可能感兴趣的:(Python基础)