python描述器的分类

python描述器的分类
python描述器的分类

本文教程操作环境:windows7系统、Python 3.9.1,DELL G3电脑。

1、非数据描述器

非数据描述器,只对类属性产生作用。当访问类属性时,将调用描述器的__get__方法。当非数据描述器是实例的变量时,实例访问非数据描述器不会调用__get__方法,只是访问了描述器类的实例。

# 示例
class Student1:
    def __init__(self):
        self.course = 'Python'
        print('Student1.__init__')
 
class Student2:
    stu1 = Student1()     # Student1()返回的是Student1类的实例
 
    def __init__(self):
        print('Student2.__init__')
 
print(Student2.stu1.course)
 
# 创建Student2的实例对象
stu2 = Student2()
print(stu2.stu1.course)
 
 
# 示例:引入描述器
class Stduent1:
    def __init__(self):
        self.course = 'Python'
        print('Stduent1.__init__')
 
    def __get__(self, instance, owner):
        print('self={} instance={} owner={}'.format(self, instance, owner))
 
class Stduent2:
    stu1 = Stduent1()
    def __init__(self):
        print('Stduent2.__init__')
 
print(Stduent2.stu1.course)
# Stduent2.stu1会访问Stduent1的实例,默认会调用__get__方法,但是__get__方法没有将实例返回,因此,Stduent2.stu1.course会报错
 
stu2 = Stduent2()
print(stu2.stu1.course)  # 一样的报错
 
 
# 示例 引入描述器
class Stduent1:
    def __init__(self):
        self.course = 'Python'
        print('Stduent1.__init__')
 
    def __get__(self, instance, owner):
        # 这里的self为Stduent1的实例. instance为实例, 如果是类访问,那么instance为None. owner是调用者的类
        print('self={} instance={} owner={}'.format(self, instance, owner))
        return self # 返回Student1的实例self
 
class Stduent2:
    stu1 = Stduent1()
    def __init__(self):
        print('Stduent2.__init__')
 
print(Stduent2.stu1.course)
 
stu2 = Stduent2()
print(stu2.stu1.course)

2、数据描述器

数据描述器,针对类属性和实例属性都产生作用。当访问或者修改此属性时,将调用相应的__get__或者__set__方法。

# 示例1:
class Student1:
    def __init__(self):
        self.course = 'Python'
        print('Student1.__init__')
 
    def __get__(self, instance, owner):
        # 这里的self为Student1的实例. instance为实例, 如果是类访问,那么instance为None. owner是调用者的类
        print('self={} instance={} owner={}'.format(self, instance, owner))
        return self   # 返回Student1的实例self
 
class Student2:
    stu1 = Student1()
 
    def __init__(self):
        print('Student2.__init__')
        self.y = Student1()   # 没有调用__get__方法
 
print(Student2.stu1.course)
 
stu2 = Student2()
print(stu2.y)
 
 
# 示例,数据描述器
class Student1:
    def __init__(self):
        self.course = 'Python'
        print('Student1.__init__')
 
    def __get__(self, instance, owner):
        print('self={} instance={} owner={}'.format(self, instance, owner))
        return self
 
    def __set__(self, instance, value):
        print('self={} instance={} value={}'.format(self, instance, value))
        self.course = value
 
class Student2:
    stu1 = Student1()
 
    def __init__(self):
        print('Student2.__init__')
        self.y = Student1()   # 调用了__get__方法
 
print(Student2.stu1.course)
 
stu2 = Student2()
print(stu2.stu1)

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注