python学习笔记,主要参考资料1、Learning Python: from Beginner to Master, 2、草根学 Python 任何问题欢迎邮件:admin@franciswu.top)
重过一遍python基础知识的时候发现之前对于对象描述器的理解有错,做个笔记。
定义
描述器是一个有“绑定行为”的对象属性(“object attribute”)。这些方法是 __get__()
, __set__()
, 和 __delete__()
。有这些方法的对象叫做描述器。默认对属性的访问控制是对象的字典中(__dict__
)
的获取(get),设置(set),删除(delete)。
a.x
的获取顺序为a.__dict__['x']
,然后type(a).__dict['x']
,然后查找a的父类。如果查找到的值是一个描述器,python会调用描述器的方法来覆盖默认的控制行为。
例子一
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
class User(object):
def __init__(self, name='两点水', sex='男'):
self.sex = sex
self.name = name
def __get__(self, obj, objtype):
print('获取 name 值')
return self.name
def __set__(self, obj, val):
print('设置 name 值')
self.name = val
class MyClass(object):
x = User('两点水', '男')
y = 5
if __name__ == '__main__':
m = MyClass()
print(m.x)
print('\n')
m.x = '三点水'
print(m.x)
print('\n')
print(m.x)
print('\n')
print(m.y)
输出:
获取 name 值
两点水
设置 name 值
获取 name 值
三点水
获取 name 值
三点水
5
本例子中对于描述器的使用接近于类的属性,可以看出get和set的调用关系。
例子二
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
class Meter(object):
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class Foot(object):
def __get__(self, instance, owner):
return instance.meter * 3.2808
def __set__(self, instance, value):
instance.meter = float(value) / 3.2808
class Distance(object):
meter = Meter()
foot = Foot()
if __name__ == '__main__':
d = Distance()
print(d.meter, d.foot)
d.meter = 1
print(d.meter, d.foot)
d.meter = 2
print(d.meter, d.foot)
输出:
0.0 0.0
1.0 3.2808
2.0 6.5616
在上面例子中,在还没有对 Distance 的实例赋值前, 我们认为 meter 和 foot 应该是各自类的实例对象, 但是输出却是数值。这是因为 __get__
发挥了作用.
我们只是修改了 meter ,并且将其赋值成为 int ,但 foot 也修改了。这是 __set__
发挥了作用.
描述器对象 (Meter、Foot) 不能独立存在, 它需要被另一个所有者类 (Distance) 所持有。描述器对象可以访问到其拥有者实例的属性,比如例子中 Foot 的 instance.meter
。