赞
赏
Python 的 描述符 的主要作用就是控制 类 的行为,或者说对类的操作进行 hook,大部分时候是用来拦截对实例 属性 的访问。
只要类中有 __get__()
, __set__()
, 和 __delete__()
其中之一的方法,那么它就是一个描述器。我们对一个类进行操作,逃不开这三种方法,我们需要控制什么操作,就 hook 哪个方法。
使用描述符,控制类属性操作
print("嗨客网(www.haicoder.net)")
class Integer(object):
def __init__(self, name):
self.name = name
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError('Expected an int')
instance.__dict__[self.name] = value
class Point(object):
x = Integer('x')
y = Integer('y')
def __init__(self, x, y):
self.x = x
self.y = y
def info(self):
print("x =", self.x, "y =", self.y)
p = Point(2, 3)
p.info()
程序运行后,控制台输出如下:
我们定义了一个 Integer 类,类中定义了 __set__()
方法,因此 Integer 是一个描述器。在 __set__()
方法里,我们判断传入的值 value 是否是 int类型,如果不是,那么抛出异常,否则,使用 __dict__
设置原始值。
最后,我们定义了一个 Point 类,并在 Point 类里面使用 Integer 类定义了 x 和 y 两个类属性,最后,我们给 x 和 y 都赋值为整数,程序正常。现在我们将程序修改为如下:
print("嗨客网(www.haicoder.net)")
class Integer(object):
def __init__(self, name):
self.name = name
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError('Expected an int')
instance.__dict__[self.name] = value
class Point(object):
x = Integer('x')
y = Integer('y')
def __init__(self, x, y):
self.x = x
self.y = y
def info(self):
print("x =", self.x, "y =", self.y)
p = Point(2, 3.3)
p.info()
程序运行后,控制台输出如下:
此时,我们将 y 的值设置为了 3.3,不再是 int 类型,此时程序抛出了异常,因此,我们使用描述符实现了对参数 x 和 y 的整数类型的限制。
Python 的描述符的主要作用就是控制类的行为,或者说对类的操作进行 hook,大部分时候是用来拦截对实例属性的访问。
只要类中有 __get__()
, __set__()
, 和 __delete__()
其中之一的方法,那么它就是一个描述器。我们对一个类进行操作,逃不开这三种方法,我们需要控制什么操作,就 hook 哪个方法。