Python中property实现原理以及纯python实现

一.Python中property的实现原理探究

在python中访问类(class)的属性可以通过实例化的类对象名称.属性名称(obj.attribute)来访问类中定义的属性,那类中定义的函数可不可以直接通过类名来进行对应的功能操作呢,答案肯定是可以的,property类修饰类方法后的作用就是让类的定义的函数能像类属性一样进行访问和修改

1.1 如何获取类(class)中属性

直接上代码

class Wrap(object):

    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        print('instance-----', self.name, instance, owner)
        return self.name


class Test:

    x = Wrap('bob')


t = Test()
print(t.x)
输出结果为:
instance----- bob <__main__.Test object at 0x0000027D756AB8D0> <class '__main__.Test'>
bob

从上面例子我们可以大致知道,当类中定义了__get__()方法后,直接调用类属性会执行__get__()方法,由此可知我们如果想实现property类,除了获取属性之外应该还可以设置属性,即实现__set__()方法

1.2 Property简洁版实现
class PropertySingle:

    def __init__(self, f_get, f_set):
        self.f_get = f_get
        self.f_set = f_set

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return self.f_get(instance)

    def __set__(self, instance, value):
        return self.f_set(instance, value)

    def setter(self, f_set):
        return PropertySingle(self.f_get, f_set)

这里思维需要进行一个转弯,基于修饰符@function.setter,我们知道function已经是property的实例,那么,我们如果要实现setter函数来模拟实现property这个类,那么__set__()这个函数的函数体中是要返回描述符对象,并该对象是有 __set__ 的,那 property 不就正好满足吗,所以这里的处理方式是 setter 函数会返回一个新的 property 实例

1.3 Property的纯python版实现
class Property:

    def __init__(self, f_get=None, f_set=None, f_del=None, doc=None):
        self.f_get = f_get
        self.f_set = f_set
        self.f_del = f_del
        self.doc = doc
        if doc is None and f_get is not None:
            doc = f_get.__doc__
        self.__doc__ = doc

    def __get__(self, instance, owner):
        if instance is None:
            return self
        if self.f_get is None:
            raise AttributeError('unreadable attribute')
        return self.f_get(instance)

    def __set__(self, instance, value):
        if self.f_set is None:
            raise AttributeError("can't set attribute")
        return self.f_set(instance, value)

    def __delete__(self, instance):
        if self.f_del is None:
            raise AttributeError("can't delete attribute")
        self.f_del(instance)

    def getter(self, f_get):
        return type(self)(f_get, self.f_set, self.f_del, self.__doc__)

    def setter(self, f_set):
        return type(self)(self.f_get, f_set, self.f_del, self.__doc__)

    def deleter(self, f_del):
        return type(self)(self.f_get, self.f_set, f_del, self.__doc__)

在创建新的 proptery 实例中使用的是 type(self)(…) ,这是因为考虑到了 proptery 可能被继承,type(self)属于元类中构建新类的一种用法

总结:proptery 主要依赖于描述符的机制。proptery 内置也成为了 Python 的一个特性,它的内部实现原理很简单,实现__get__(),__set__()这些描述性方法

猜你喜欢

转载自blog.csdn.net/qq_42707967/article/details/113979085