Python 的描述符 descriptor详解

2020-06-22 09:52 来源:易采站长站 作者:易采站长站整理 点击: 评论:

A-A+

原标题:Python 的描述符 descriptor详解

Python 在 2.2 版本中引入了descriptor(描述符)功能,也正是基于这个功能实现了新式类(new-styel class)的对象模型,同时解决了之前版本中经典类 (classic class) 系统中出现的多重继承中的 MRO(Method Resolution Order) 问题,另外还引入了一些新的概念,比如 classmethod, staticmethod, super, Property 等。因此理解 descriptor 有助于更好地了解 Python 的运行机制。

那么什么是 descriptor 呢?

简而言之:descriptor 就是一类实现了__get__(), __set__(), __delete__()方法的对象。

Orz…如果你瞬间顿悟了,那么请收下我的膝盖;
O_o!…如果似懂非懂,那么恭喜你!说明你潜力很大,咱们可以继续挖掘:

引言

对于陌生的事物,一个具体的栗子是最好的学习方式,首先来看这样一个问题:假设我们给一次数学考试创建一个类,用于记录每个学生的学号、数学成绩、以及提供一个用于判断是否通过考试的check 函数:


class MathScore():

def __init__(self, std_id, score):
self.std_id = std_id
self.score = score

def check(self):
if self.score >= 60:
return 'pass'
else:
return 'failed'

很简单一个示例,看起来运行的不错:


xiaoming = MathScore(10, 90)

xiaoming.score
Out[3]: 90

xiaoming.std_id
Out[4]: 10

xiaoming.check()
Out[5]: 'pass'

但是会有一个问题,比如手一抖录入了一个负分数,那么他就得悲剧的挂了:


xiaoming = MathScore(10, -90)

xiaoming.score
Out[8]: -90

xiaoming.check()
Out[9]: 'failed'

这显然是一个严重的问题,怎么能让一个数学 90+ 的孩子挂科呢,于是乎一个简单粗暴的方法就诞生了:


class MathScore():

def __init__(self, std_id, score):
self.std_id = std_id
if score < 0:
raise ValueError("Score can't be negative number!")
self.score = score

def check(self):
if self.score >= 60:
return 'pass'
else:
return 'failed'

 
上面再类的初始化函数中增加了负数判断,虽然不够优雅,甚至有点拙劣,但这在实例初始化时确实工作的不错:


xiaoming = MathScore(10, -90)

Traceback (most recent call last):

File "<ipython-input-12-6faad631790d>", line 1, in <module>
xiaoming = MathScore(10, -90)

File "C:/Users/xu_zh/.spyder2-py3/temp.py", line 14, in __init__
raise ValueError("Score can't be negative number!")

ValueError: Score can't be negative number!

【易采站长站编辑:秋军】