持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情
0 环境
- 编辑器:pycharm或者vscode
- 系统版本:windows10
- vue版本:2.6.10
- vxetable版本:v3+
1 参考文章
2 描述器(Descriptor)
描述器(Descriptor)是个什么样子呢,一个类实现了__get__、set、delete,只要满足一个方法,它就是描述器。描述器还分非资料描述器(non-data descriptor)和资料描述器(data descriptor),非资料描述器(non-data descriptor)是只定义了__get__,根据non-data(翻译过来非数据),是不是可以猜测为单纯的只读。而资料描述器(data descriptor),
__set__
、__delete__
只要满足一个就可以,跟数据打交道(写入)。根据上面的参考文章,__get__(self, instance, owner)
或其他两个,如下代码:我把父看作为父节点(只是为了好理解,不一定对),我父节点建了一个child了(不要在初始化中调用建child,不然会被当作为普通的实例),然后它指向子节点,一旦调用了,我把子看作为子节点,我的子节点肯定要知道,我的父实例和父类是谁吧(从哪里来的问题),只是为了帮助自己好理解,虽然不太对。
class 子:
def __get__(xx):
xxx
def __set__(xxx):
xxx
class 父:
child = 子()
父().child
2 初步使用
如下代码:
Parent类中定义两个child的,一个是类变量,一个是实例变量,当我只是调用Parent()的时候,打印该实例,进入到Child里的__set__,将123赋值到Parent
实例里的__dict__
中。当使用p.child,会进入__get__里,最后return。
class Child:
def __init__(self, a, b):
self.a = a
self.b = b
def __get__(self, instance, cls):
print(f"instance --> {instance}, cls --> {cls}")
if instance:
return instance.__dict__[self.a]
def __set__(self, instance, value):
print(f"instance --> {instance}, value --> {value}")
instance.__dict__[self.a] = value
class Parent:
child = Child("a", "b")
def __init__(self):
self.child = 123
p = Parent()
print("前 -->", p.__dict__)
print(p.child)
print("后 -->", p.__dict__)