Python 描述符(Descriptor)入门

Python描述符入门

什么是Python描述符?

Python描述符是一种实现了特定协议的对象,允许自定义属性访问和赋值的行为,是Python属性的核心机制之一。描述符常用于创建高级对象,例如ORM(对象关系映射)模型、表单验证和属性缓存等。在Python中,一个描述符必须实现以下方法:

  • __get__(self, instance, owner=None):访问描述符时调用的方法,返回属性的值。
  • __set__(self, instance, value):设置描述符时调用的方法,设置属性的值。
  • __delete__(self, instance):删除描述符时调用的方法。

描述符的使用方法

使用描述符,需要创建一个类,并在其中定义上述方法。当某个属性被定义为一个描述符实例时,该实例的相关方法将被调用来访问和修改属性。以下是一个实现描述符的例子:

class Descriptor:
    def __init__(self, name=None):
        self.name = name

    def __get__(self, instance, owner=None):
        if instance:
            return instance.__dict__.get(self.name)
        return self

    def __set__(self, instance, value):
        instance.__dict__[self.name] = value

    def __delete__(self, instance):
        del instance.__dict__[self.name]

上述描述符方法中,将属性的名称保存在name参数中。__get__方法的参数instance指向拥有该属性的对象实例,owner参数指向对象的类(可选)。在返回属性值时,使用instance.__dict__.get(self.name)获取该实例中属性的值。__set__方法用来设置属性值,使用instance.__dict__[self.name] = value进行设置操作。__delete__方法用于删除属性,在这个例子中使用del instance.__dict__[self.name]来删除实例中的属性。

可以使用以上定义的描述符来定义一个类:

class Person:
    name = Descriptor('name')
    age = Descriptor('age')

使用上述类创建一个对象并尝试设置属性:

p = Person()
p.name = "Jack"
p.age = 20
print(p.name)  # 输出Jack
print(p.age)   # 输出20

描述符的应用

下面介绍两个描述符实现的例子:

描述符给属性设置只读属性

在这个例子中,我们将实现描述符来给某个属性设置只读属性。在__set__方法中,如果尝试修改值,将触发AttributeError异常。

class ReadOnlyDescriptor:
    def __init__(self, name=None):
        self.name = name

    def __get__(self, instance, owner=None):
        if instance:
            return instance.__dict__.get(self.name)
        return self

    def __set__(self, instance, value):
        raise AttributeError("Read Only Attribute")

    def __delete__(self, instance):
        del instance.__dict__[self.name]


class Person:
    name = ReadOnlyDescriptor('name')
    age = Descriptor('age')

测试代码如下:

p = Person()
p.name = "Jack"
p.age = 20
print(p.name)  # 输出Jack
# 抛出异常
try:
    p.name = "Lucy"
except AttributeError as e:
    print(e)
# 输出20
print(p.age)

描述符实现缓存属性

在这个例子中,我们将实现一个描述符来缓存一些属性,避免重复计算。在__get__方法中,如果值已经被设置过,就直接返回缓存的结果。否则计算结果并设为该属性的值,并将值保存在缓存变量cached_value中。

class CacheDescriptor:
    def __init__(self, func):
        self.func = func
        self.cached_value = None

    def __get__(self, instance, owner=None):
        if instance:
            if self.cached_value is None:
                self.cached_value = self.func(instance)
            return self.cached_value
        return self

    def __set__(self, instance, value):
        self.cached_value = value

    def __delete__(self, instance):
        self.cached_value = None


class Circle:
    def __init__(self, radius):
        self.radius = radius

    @CacheDescriptor
    def area(self):
        print("calculating area")
        return 3.14 * self.radius ** 2

测试代码如下:

c = Circle(10)
print(c.area)        # 计算面积,并输出314.0
print(c.area)        # 直接输出314.0,无需重复计算
c.radius = 5         # 修改属性后需要重新计算面积
print(c.area)        # 计算新的面积,并输出78.5

结论

以上是Python描述符的基础知识和使用方法。描述符作为Python属性的核心机制之一,可以非常灵活的定义属性的访问和修改行为,实现各种高级功能。需要注意的是,描述符是Python高级语言的一部分,初学者需要更多的实践积累经验才能熟练掌握。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 描述符(Descriptor)入门 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • python批量翻译excel表格中的英文

    下面是“Python批量翻译Excel表格中的英文”的完整实例教程。 1. 准备工作 在使用 Python 批量翻译 Excel 表格的过程中,需要先完成以下准备工作。 1.1 安装必要的库 首先需要安装必要的库,包括 pandas 和 googletrans。pandas 是 Python 中用于数据处理的库,googletrans 是用于谷歌翻译的 Py…

    python 2023年5月14日
    00
  • Python GUI程序类写法与Label介绍

    下面就是关于“Python GUI程序类写法与Label介绍”的完整攻略。 Python GUI程序类写法与Label介绍 什么是GUI程序 GUI全称为Graphical User Interface,即图形用户界面,是指使用图形方式显示的计算机操作界面。与CLI(Command-line Interface)相比,GUI更加直观、友好,操作更加简便。 P…

    python 2023年6月6日
    00
  • python3中join和格式化的用法小结

    下面我将为大家详细讲解“Python3中join和格式化的用法小结”。 一、Python3中join的用法 join()方法语法:连接符.join(需要连接的元素序列) 使用join()方法可以将一个序列中的所有元素用指定的连接符串联成一个字符串。 下面是一个示例: # 示例一 languages = [‘Python’, ‘Java’, ‘JavaScri…

    python 2023年6月2日
    00
  • pygame实现俄罗斯方块游戏(基础篇3)

    《pygame实现俄罗斯方块游戏(基础篇3)》是一篇教程,主要介绍了如何使用Python和Pygame库实现一个俄罗斯方块游戏。下面是这篇攻略的详细介绍: 1. 简介 本教程介绍了如何使用Python和Pygame库实现一个俄罗斯方块游戏。在本教程中,我们将会涵盖以下内容: Pygame基础知识介绍 游戏场景的建立 方块的图形绘制 方块的碰撞检测 方块的移动…

    python 2023年6月2日
    00
  • python使用requests模块实现爬取电影天堂最新电影信息

    以下是使用Python requests模块实现爬取电影天堂最新电影信息的攻略: Python使用requests模块实现爬取电影天堂最新电影信息 电影天堂是一个非常受欢迎的电影资源网站,以下是使用Python requests模块实现爬取电影天堂最新电影信息的攻略: 获取电影列表页面 首先,我们需要获取电影天堂的电影列表页面,以下是获取电影列表页面的示例:…

    python 2023年5月14日
    00
  • Python基于辗转相除法求解最大公约数的方法示例

    下面是“Python基于辗转相除法求解最大公约数的方法示例”的完整攻略。 一、什么是辗转相除法 辗转相除法(又称欧几里得算法)是一种求最大公约数的算法,其思路是利用较小数除较大数,然后再用除数去除余数,直到余数为 0 为止。 同时,根据裴蜀定理,如果 a 和 b 是整数,且它们的最大公约数为 d,那么关于未知数 x,y 的线性不定方程(称为裴蜀等式) $ax…

    python 2023年6月5日
    00
  • Python使用pandas导入xlsx格式的excel文件内容操作代码

    下面是“Python使用pandas导入xlsx格式的excel文件内容操作代码”的完整实例教程。 1. 导入需要的库 import pandas as pd 2. 读取Excel文件 使用pandas的read_excel()函数可以读取Excel文件。该函数的参数包括文件名、sheet名以及其他一些配置信息。 df = pd.read_excel(‘ex…

    python 2023年5月13日
    00
  • python 详解如何使用GPU大幅提高效率

    Python 如何使用 GPU 大幅提高效率 什么是GPU GPU(Graphics Processing Unit)即图形处理器,它是一种专门进行图像和视频处理的处理器。随着深度学习、机器学习等领域的兴起,GPU 也被应用于大规模并行计算、科学计算等领域,其拥有大量的浮点计算单元,可以显著加速矩阵运算等科学计算任务。目前,市场上主要有 NVIDIA 和 A…

    python 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部