1 2 | Defines descriptors, summarizes the protocol, and shows how descriptors are called. Examines a custom descriptor and several built-in Python descriptors including functions, properties, static methods, and class methods. Shows how each works by giving a pure Python equivalent and a sample application. 学习描述器不仅能提供接触到更多工具集的方法,还能更深地理解 Python 工作的原理并更加体会到其设计的优雅性。 |
class Person(object):
def __init__(self):
self.name = 'qiangzai'
p = Person()
print(p.__dict__) # {'name': 'qiangzai'}
p.age = 18 # 给p实例对象添加age属性
print(p.__dict__) # {'name': 'qiangzai', 'age': 18}
案例1 定义一个非数据描述器实例对象中只定义了__get__()的描述器称为非数据描述器(它们通常用于方法,但也可以用于其他用途)。
class Descriptor(object):
def __get__(self, instance, owner):
# self 指A的实例对象 owner/instance指的是调用方的类及类的实例
print(self, instance, owner)
class Person(object):
# 注意一定是类属性,而不是实例属性
name = Descriptor()
p = Person()
p.name # <__main__.Descriptor object at 0x10c6c1940> <__main__.Person object at 0x10c782668> <class '__main__.Person'>
'''
p.name的调用顺序
1. p先去自己的__dict__去寻找name, 没有找到
2. p又去自己的类 Person的__dict__找name, 找到了
3. 找到以后返回name对应的value是一个描述器,会调用描述器的__get__方法
'''
Person.name # <__main__.Descriptor object at 0x10a3cd940> None <class '__main__.Person'>
'''
Person.name的调用顺序
1. Person去自己的属性Person.__dict__中找到了name
2. 发现找到的name对应的value是一个描述器,会调用描述器的__get__方法
'''
class Descriptor(object):
def __init__(self):
self.cls_name = 'Descriptor'
def __get__(self, instance, owner):
# 将实例对象self本身返回
return self
class Person(object):
name = Descriptor()
p = Person()
print(p.name.cls_name) # Descriptor
class Descriptor(object):
def __init__(self):
self.cls_name = 'Descriptor'
def __get__(self, instance, owner):
# 将实例对象self本身返回
return self
class Person(object):
name = Descriptor()
def __init__(self):
self.name = 'qiangzai'
p = Person()
print(p.name) # qiangzai
print(p.name.cls_name) # AttributeError: 'str' object has no attribute 'cls_name'
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |