深入探讨Python中的元编程:装饰器与元类
Python以其简洁明了的语法和强大的标准库,成为许多开发者的首选语言。而在高级开发中,元编程(Metaprogramming)是一个非常强大的工具,可以极大地提升代码的灵活性和可复用性。本文将深入探讨Python中的元编程,重点介绍装饰器和元类的应用与原理。
装饰器
装饰器是一种高级函数,用于修改其他函数或类的行为。它允许开发者在不修改原有代码的情况下,为函数或类添加额外的功能。
函数装饰器
函数装饰器的基本形式是一个接受函数作为参数并返回一个新函数的高阶函数。以下是一个简单的例子:
def my_decorator(func):def wrapper(*args, **kwargs):print("Something is happening before the function is called.")result = func(*args, **kwargs)print("Something is happening after the function is called.")return resultreturn wrapper@my_decorator
def say_hello():print("Hello!")say_hello()
在这个例子中,my_decorator装饰器在say_hello函数前后添加了打印操作。使用@my_decorator语法糖,我们可以更简洁地应用装饰器。
类装饰器
类装饰器与函数装饰器类似,但它们接受一个类作为参数并返回一个新类。例如:
def singleton(cls):instances = {}def get_instance(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return get_instance@singleton
class MyClass:passobj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2) # True
在这个例子中,singleton装饰器确保MyClass只有一个实例。
元类
元类是用于创建类的类。通常,类是由type创建的,但通过定制元类,我们可以控制类的创建过程。
自定义元类
自定义元类需要继承自type,并重写其__new__或__init__方法。例如:
class MyMeta(type):def __new__(cls, name, bases, dct):dct['greet'] = lambda self: print('Hello from', self.__class__.__name__)return super().__new__(cls, name, bases, dct)class MyClass(metaclass=MyMeta):passobj = MyClass()
obj.greet() # Hello from MyClass
在这个例子中,MyMeta元类在创建MyClass时,动态地为其添加了一个greet方法。
元类的实际应用
元类在许多框架中都有广泛的应用,例如Django ORM。通过元类,Django可以在定义模型类时,自动生成数据库表的字段和关系。
以下是一个简单的ORM示例:
class Field:def __init__(self, name):self.name = nameclass ModelMeta(type):def __new__(cls, name, bases, dct):if name != 'BaseModel':fields = {k: v for k, v in dct.items() if isinstance(v, Field)}dct['_fields'] = fieldsreturn super().__new__(cls, name, bases, dct)class BaseModel(metaclass=ModelMeta):passclass User(BaseModel):id = Field('id')name = Field('name')user = User()
print(user._fields) # {'id': <__main__.Field object at 0x...>, 'name': <__main__.Field object at 0x...>}
在这个示例中,ModelMeta元类自动收集User类中的字段定义,并将它们存储在_fields属性中。
写在最后
通过装饰器和元类,Python的元编程为开发者提供了强大的工具,可以简化代码、增强功能并提高代码的可维护性。掌握这些高级特性,不仅能够提升开发效率,还能为代码带来更多的灵活性和扩展性。在实际项目中,合理地使用装饰器和元类,可以有效地应对复杂的编程需求。
相关文章:
深入探讨Python中的元编程:装饰器与元类
Python以其简洁明了的语法和强大的标准库,成为许多开发者的首选语言。而在高级开发中,元编程(Metaprogramming)是一个非常强大的工具,可以极大地提升代码的灵活性和可复用性。本文将深入探讨Python中的元编程ÿ…...
MaxKb/open-webui+Ollama运行模型
准备:虚拟机:centos7 安装Docker:首先,需要安装Docker,因为Ollama和MaxKB都是基于Docker的容器。使用以下命令安装Docker: sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum…...
2-requests模块(6节课学会爬虫)
2-requests模块(6节课学会爬虫) 1,安装requests2,发送get,post请求,获取响应3,response的方法方法一(Response.text)方法二(response.content.decode()&#…...
使用ECharts创建动态数据可视化图表
使用ECharts创建动态数据可视化图表 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 在现代Web应用开发中,数据可视化是至关重要的一环。ECharts作…...
Nacos配置中心客户端源码分析(一): 客户端如何初始化配置
本文收录于专栏 Nacos 推荐阅读:Nacos 架构 & 原理 文章目录 前言一、NacosConfigBeanDefinitionRegistrar二、NacosPropertySourcePostProcessor三、AbstractNacosPropertySourceBuilder总结「AI生成」 前言 专栏前几篇文章主要讲了Nacos作为服务注册中心相关…...
gin数据解析,绑定和渲染
一. 数据解析和绑定 1.1 Json数据解析和绑定 html文件: <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...
Django 对模型创建的两表插入数据
1,添加模型 Test/app8/models.py from django.db import modelsclass User(models.Model):username models.CharField(max_length50, uniqueTrue)email models.EmailField(uniqueTrue)password models.CharField(max_length128) # 使用哈希存储密码first_name …...
Lua: 轻量级多用途脚本语言
Lua 是一种高效而轻量级的脚本语言,具备强大的扩展性和灵活性,广泛应用于游戏开发、嵌入式系统、Web 应用等多个领域。本文将深入探讨 Lua 的特性、应用场景以及如何使用 Lua 进行开发。 1. Lua 的起源与发展 Lua 的发展始于上世纪90年代初,…...
PotPlayer安装及高分辨率设置
第1步: 下载安装PotPlayer软件 PotPlayer链接:https://pan.baidu.com/s/1hW168dJrLBonUnpLI6F3qQ 提取码:z8xd 第2步: 下载插件,选择系统对应的位数进行运行,该文件不能删除,删除后将失效。 …...
实现写入缓存策略的最佳方法探讨
实现写入缓存策略的最佳方法探讨 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在软件开发中实现写入缓存策略的最佳方法。缓存在提升应用性能和…...
【Day03】0基础微信小程序入门-学习笔记
文章目录 视图与逻辑学习目标页面导航1. 声明式导航2. 编程式导航3. 导航传参 页面事件1. 下拉刷新2. 上拉触底3.扩展-自定义编译模式 生命周期1. 简介2. 生命周期函数3. 应用的生命周期函数4. 页面生命周期函数 WXS脚本1. 概述2. 基础语法3. WXS的特点4. 使用WXS处理手机号 总…...
libctk shared library的设计及编码实践记录
一、引言 1.1 <libctk>的由来 1.2 <libctk>的设计理论依据 1.3 <libctk>的设计理念 二、<libctk>的依赖库 三、<libctk>的目录说明 四、<libctk>的功能模块及使用实例说明 4.1 日志模块 4.2 mysql client模块 4.3 ftp client模块 4…...
【代码随想录训练营】【Day 65】【图论-2】| 卡码 99
【代码随想录训练营】【Day 65】【图论-2】| 卡码 99 需强化知识点 深度搜索和广度搜索 题目 99. 岛屿数量 思想:遍历到为1的节点,再搜索标记,每遇到新的陆地节点,增加计数 深度搜索广度搜索:此处用 [] 作为待遍…...
【动态规划】139. 单词拆分
139. 单词拆分 难度:中等 力扣地址:https://leetcode.cn/problems/word-break/description/ 问题描述 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字…...
【C++】空指针访问成员函数
空指针访问成员函数 C中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针 如果用到this指针,需要加以判断保证代码的健壮性 class Animal { public:void fun1() {//正常的成员函数}void fun2() {if (this NULL) {return;//如果没有这个…...
Linux的IO易错点总结
本文主要记录IO的一些易错操作。 阻塞IO和非阻塞IO,一般都是针对数据读取的,因为write是主动行为,不存在阻塞这一说。 非阻塞式IO,一般都要配合while轮询来读取数据。 IO多路复用 当只检测一路IO的时候,和普通IO的作…...
【Android面试八股文】说一说你对Android中的Context的理解吧
文章目录 一、Context是什么?1.1 主要功能和用途1.2 如何获取 Context 实例?1.3 注意事项二、Context 类的层次结构三、Context的数量四、Context的注意事项五、Android 中有多少类型的 Context,它们有什么区别 ?六、Contextlmpl实例是什么时候生成的,在 Activity 的 oncr…...
AI在音乐创作中的角色:创造还是毁灭?
目录 一、基本情况介绍 二、近期新闻 三、AI生成音乐方面的商业模式 四、人工智能和音乐人可能的合作模式 五、人们如何借助AI来创作音乐 六、人工智能在创意产业引发的伦理道德问题 七、如何平衡技术发展与提高人类创造积极性的关系? 总结 一、基本情况介绍…...
[深入理解DDR] 总目录
依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解DDR》 蓝色的是传送门,点击链接即可到达指定文章。 图。 DDR 分类 导论 [RAM] DRAM 导论:DDR4 | DDR5 | LPDDR5 | GDRR6 | HBM 应运而生 运存与内存?内存与存…...
模板方法模式在金融业务中的应用及其框架实现
引言 模板方法模式(Template Method Pattern)是一种行为设计模式,它在一个方法中定义一个算法的框架,而将一些步骤的实现延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。在金融业务中ÿ…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
高保真组件库:开关
一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...
python读取SQLite表个并生成pdf文件
代码用于创建含50列的SQLite数据库并插入500行随机浮点数据,随后读取数据,通过ReportLab生成横向PDF表格,包含格式化(两位小数)及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...
