描述符

Posted ch2020

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了描述符相关的知识,希望对你有一定的参考价值。

描述符的本质是一个新式类,在这个新式类中,至少实现了__get__()、__set__()、__delete__()中的一个,这也被称为描述符协议

__get__() :调用一个属性时,触发

__set__()  :为一个属性赋值时,触发

__delete__()   :采用del删除属性时,触发

数据描述符:至少实现了__get__()和__set__()

非数据描述符:没有实现__set__() 

 1 class Foo:
 2     a = 4
 3 
 4     def __init__(self):
 5         self.name = alex
 6         self.age = 18
 7 
 8     def __get__(self, instance, owner):
 9         print(=====执行get 方法)
10 
11     def __delete__(self, instance):
12         print(调用dele)
13 
14     def __set__(self, instance, value):
15         print(调用set)
16 
17 
18 class New:
19     x = Foo()
20 
21     def __init__(self, n):
22         self.x = n
23     # def test(self):
24     #     print(self.x.a)
25 
26 
27 n1 = New(10)
28 print(n1.__dict__)
29 输出:
30 调用set
31 {}

相当于New类中的x属性被Foo() 代理了

总结:描述符是在一个类中定义,且只能在类属性中定义,不能再类函数中定义,包括__init__函数(初始化函数)。

 1 class Foo:
 2     a = 4
 3 
 4     def __init__(self):
 5         self.name = alex
 6         self.age = 18
 7 
 8     def __get__(self, instance, owner):
 9         print(=====执行get 方法)
10 
11     def __delete__(self, instance):
12         print(调用dele)
13 
14     def __set__(self, instance, value):
15         print(调用set)
16         instance.__dict__[x] = value
17 
18 
19 class New:
20     x = Foo()
21 
22     def __init__(self, n):
23         self.x = n
24     # def test(self):
25     #     print(self.x.a)
26 
27 
28 n1 = New(10)
29 # n1.y = 545
30 print(n1.__dict__)
31 输出:
32 调用set
33 {x: 10}

调用优先级:

1.类属性     2.数据描述符    3.实例属性    4.非数据描述符     5.找不到的属性触发__getatr__()

 1 class Foo:
 2     a = 4
 3 
 4     def __init__(self):
 5         self.name = alex
 6         self.age = 18
 7 
 8     def __get__(self, instance, owner):
 9         print(=====执行get 方法)
10 
11     def __delete__(self, instance):
12         print(调用dele)
13 
14     def __set__(self, instance, value):
15         print(调用set)
16         instance.__dict__[x] = value
17 
18 
19 class New:
20     x = Foo()
21 
22     # def __init__(self, n):
23     #     self.x = n
24     # def test(self):
25     #     print(self.x.a)
26 
27 
28 print(New.x)   #  从类属性中找,直接触发描述符
29 # New.x = 2   # 按照优先级,先访问类属性,类属性没有,直接创建,不会访问描述符
30 # # print(New.__dict__)
31 # # n1 = New()
32 n1 = New()
33 n1.x = 3   # 描述符大于实例属性
34 n1.x
35 输出:
36 =====执行get 方法
37 None
38 调用set
39 =====执行get 方法

 

以上是关于描述符的主要内容,如果未能解决你的问题,请参考以下文章

编写一个程序, 将 a.txt 文件中的单词与 b.txt 文件中的 单词交替合并到 c.txt 文件中, a.txt 文件中的单词用回车符 分隔, b.txt 文件中用回车或空格进行分隔。(代码片段

Java字符代码中干掉制表符回车符和换行符

通过 Java 正则表达式提取 semver 版本字符串的片段

android - 调整片段大小

Java方法

Java初识方法