python元编程详解
什么是元编程
软件开发中很重要的一条原则就是“不要重复自己的工作(Don’t repeat youself)”,也就是说当我们需要复制粘贴代码时候,通常都需要寻找一个更加优雅的解决方案,在python中,这类问题常常会归类为“元编程”
元编程目的
是创建函数和类,并用他们操作代码(例如修改,生成,或者包装自己已有的代码)。尽可能的使代码优雅简洁。具体而言,通过编程的方法,在更高的抽象层次上对一种层次的抽象的特性进行修改
元编程应用
给函数添加一个包装(装饰器)
注意:对wraps装饰器的使用进行补充说明,在类装饰器中使用闭包会导致生成的对象不再是被装饰的类的实例,而是在装饰器函数创建的子类的实例,这会影响__name__和__doc__等属性,在上篇我们使用@wraps装饰器对函数装饰器进行操作让问题得到解决,但在类装饰器中这一方法无效。
元类
在理解元类之前,您需要掌握Python中的类。Python对于从Smalltalk语言借用的类是非常奇怪的。在大多数语言中,类只是描述如何生成对象的代码片段。在Python中也是如此:
1 2 3 4 5 6 7 |
|
一旦使用关键字class
,Python就会执行它并创建一个OBJECT。指示
1 2 3 |
|
在内存中创建一个名为“ObjectCreator”的对象。这个对象(类)本身能够创建对象(实例),这就是为什么它是一个类。但是,它仍然是一个对象,因此:
-
- 您可以将其分配给变量
- 你可以复制它
- 你可以添加属性
- 您可以将其作为函数参数传递
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
动态创建类
由于类是对象,因此您可以像任何对象一样动态创建它们。首先,您可以使用class
以下命令在函数中创建类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
但它还不是我们想要的,创建类应该有更优的方法,由于类是对象,因此它们必须由某些东西生成。
使用class
关键字时,Python会自动创建此对象。但与Python中的大多数内容一样,它为您提供了手动执行此操作的方法。我们可用通过type函数查看对象的类型:
1 2 3 4 5 6 7 8 |
|
type除了可以查看数据类型外,还
有一个特殊的能力,它也可以动态创建类。type
可以将类的描述作为参数,并返回一个类。查看type内部原理
:
1 2 3 |
|
例如:
1 2 |
|
可以通过以下方式手动创建:
1 2 3 4 5 |
|
type
接受字典来定义类的属性。所以:
1 2 |
|
可以翻译成:
1 |
|
并用作普通类:
1 2 3 4 5 6 7 8 9 |
|
当然,你可以继承它,所以:
1 2 |
|
会解释成:
1 2 3 4 5 |
|
最后,如果想要为我们创建的类添加方法,只需使用正确的签名定义函数并将其指定为属性即可。
1 2 3 4 5 6 7 8 9 10 11 |
|
在动态创建类之后,您可以添加更多方法,就像向正常创建的类对象添加方法一样。
1 2 3 4 5 6 |
|
在Python中,类是对象,您可以动态地动态创建类。这是Python在您使用关键字时所执行的操作class
,它通过使用元类来实现。
什么是元类(终于讲到重点了)
元类是创建类的“类”。我们可以定义类来创建实例,python一切皆对象,类也不列外,它是通过元类来创建。类是创建实例的蓝图,元类是创建类的蓝图。可以很容易地看出,Python类中也需要是第一类对象才能启用此行为。
例如:
1 2 |
|
通过type来创建:
1 |
|
这是因为该函数type
实际上是一个元类。type
是Python用于在幕后创建所有类的元类。
为什么是小写type而不是大学Type?
type与str
创建字符串对象int
的类创建整数对象的类类似,它也只是创建类对象的类。我们通过检查__class__
属性来查看。
一切,一切,一切重要的事情说三遍,都是Python中的一个对象。这包括整数,字符串,函数和类。所有这些都是对象。所有这些都是从一个类创建的:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
那么__class__
的__class__
?
1 2 3 4 5 6 7 8 |
|
因此,元类只是创建类对象的东西。我们也称它为类工厂
type
是Python使用的内置元类,我们也可以创建自己的元类。
__mataClass__属性
在Python 2中,我们在编写类时添加属性:
1 2 3 |
|
如果引用__mataClass__属性,python将使用元类类创建Foo,但是这样class Foo(object),类对象Foo并不是在内存中创建的
Python将会在父类中查找__metaclass__,如果没有,就继续向父类的父类查找,如果还是没有,就在模块中找,还是没有的话就用缺省的MetaClass即type
创建类。
当你这样做时:
1 2 |
|
Python会执行以下操作:
如果有__metaclass__
属性,将会在内存中创建一个类对象,名称Foo
使用是__metaclass__
。如果Python找不到__metaclass__
,它将__metaclass__
在MODULE级别查找,并尝试执行相同的操作(但仅适用于不继承任何内容的类,基本上是旧式类)。
如果还是找不到__metaclass__
,它将使用Bar
's(第一个父级)自己的元类(可能是默认的type
)来创建类对象。
Python中的元类3
在Python 3中更改了设置元类的语法:
1 2 |
|
即__metaclass__
不再使用该属性,而是支持基类列表中的关键字参数。但是并不会影响元类的功能。
python3中我们可以将属性作为关键字参数传递给元类,如下所示:
1 2 |
|
自定义元类
一个类没有声明自己的元类,默认他的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类
自定义元类的主要目的是:
-
- 拦截类的创建
- 读取类的信息,可以做修改
- 返回新的类
通过传入不同的字符串动态的创建不同的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
用type创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
让type创建的类继承一个基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
但是在实际编码中,我们一般不直接用type去创建类,而是用元类的写法,自定义一个元类metaclass去创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
还有一个典型的自定义元类例子就是Django ORM。
元类的主要用例是创建API。
它允许您定义如下内容:
class Person(models.Model):name = models.CharField(max_length=30)age = models.IntegerField()
但是如果你这样做:
guy = Person(name='bob', age='35')
print(guy.age)
它不会返回一个IntegerField
对象。它将返回一个int
,甚至可以直接从数据库中获取它。
因为models.Model
定义__metaclass__
它会使用一些魔法将Person
您刚刚使用简单语句定义的内容转换为数据库字段的复杂sql。
Django通过公开一个简单的API并使用元类,从这个API中重新创建代码来完成幕后的实际工作,从而使复杂的外观变得简单。
相关文章:
python元编程详解
什么是元编程 软件开发中很重要的一条原则就是“不要重复自己的工作(Don’t repeat youself)”,也就是说当我们需要复制粘贴代码时候,通常都需要寻找一个更加优雅的解决方案,在python中,这类问题常常会归类…...
为什么文档对 SaaS 公司至关重要?
在过去十年左右的时间里,SaaS的兴起使全球数百家公司成为家喻户晓的公司。但他们并不是仅仅依靠产品的力量到达那里的。客户服务和支持是使一切在幕后顺利进行的原因——其中很大一部分是文档。以正确的风格和正确的位置在您的网站上找到适当的用户文档对于将浏览器…...
Echarts 实现电池效果的柱状图
第022个点击查看专栏目录本示例是解决显示电池电量状态的柱状图,具体的核心代码请参考源代码。 文章目录示例效果示例源代码(共102行)相关资料参考专栏介绍示例效果 示例源代码(共102行) /* * Author: 还是大剑师兰特…...
计算机网络高频知识点(一)
目录 一、http状态码 二、浏览器怎么数据缓存 三、强缓存与协商缓存 1、强缓存 2、协商缓存 四、简单请求与复杂请求 五、PUT 请求类型 六、GET请求类型 七、GET 和 POST 的区别 八、跨域 1、什么时候会跨域 2、解决方式 九、计算机网络的七层协议与五层协议分别指…...
JavaScript split()方法
JavaScript split()方法 目录JavaScript split()方法一、定义和用法二、语法三、参数值四、返回值五、更多实例5.1 省略分割参数5.2 使用limit参数5.3 使用一个字符作为分割符一、定义和用法 split() 方法用于把一个字符串分割成字符串数组。 二、语法 string.split(separat…...
前端面试题 —— 性能优化
目录 一、CDN的作用 二、CDN的使用场景 三、懒加载的概念 四、懒加载与预加载的区别 五、documentFragment 是什么?用它跟直接操作 DOM 的区别是什么? 六、常见的图片格式及使用场景 七、懒加载的特点 八、如何优化动画? 九、如何提⾼…...
我的周刊(第080期)
我的信息周刊,记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。🎯 项目stable-diffusion-webui-docker[1]基于 Docker 的一…...
操作系统——7.进程的定义,组成,组成方式和特征
目录 1.概述 编辑2.定义 2.1单道程序 2.2多道程序 2.3进程定义 3.进程的组成 3.1进程的组成内容 3.2 PCB中的内容 4.进程的组织 4.1进程的两种组织方式 4.2链接方式 4.3索引方式 5.进程的特征 6.小结 这篇文章,我们主要来学习一下进程的定义࿰…...
CRI-O, Containerd, Docker, Postman等概念介绍
参考:Docker,containerd,CRI,CRI-O,OCI,runc 分不清?看这一篇就够了Docker, containerd, CRI-O and runc之间的区别? Docker、Podman、Containerd 谁才是真正王者?CRI-O …...
【原创】java+swing+mysql设备预约管理系统设计与实现
我们在办公室或者学校实验室的,经常需要使用一些设备,因此需要提前租借。今天我们主要介绍如何使用javaswing和mysql数据库去完成一个设备预约管理系统,方便用户进行设备管理和预约。 功能分析: 设备预约管理系统主要是为了方便…...
7、kubernetes(k8s)Dashboard 安装
本文内容以语雀为准 说明 Kubernetes Dashboard 是一个通用的、基于Web的UI,用于Kubernetes集群管理。 它允许用户管理群集中运行的应用程序并对其进行故障排除,以及管理群集本身。 不同 Kubernetes Dashboard 支持的 Kubernetes 版本不同,…...
数学小课堂:虚数的媒介工具作用(虚构一个现实中不存在的概念,来解决现实问题)
文章目录 引言I 预备知识1.1 平方根1.2 三次方程1.3 极坐标II 虚数2.1 虚数的来源2.2 理解虚数存在的必要性2.3 虚数的影响III 复数3.1 人类认知升级的过程3.2 数字的扩展历史3.3 复数的用途引言 虚数的来源和存在的必要性:三次方程是一定有实数解的,因此根号里面负数的问题…...
3.抽象工厂模式(Abstract Factory)
与工厂模式对比 工厂模式 工厂模式是类创建模式。在工厂模式中,只需要生产同一种产品,只不过是生产厂家不同。 所以产品类的设计: 抽象的产品类Product具体的产品类Product_A,Product_B, Product_C, Product_D…… 工厂的设计…...
synchronized底层如何实现?什么是锁的升级、降级?
第16讲 | synchronized底层如何实现?什么是锁的升级、降级? 我在上一讲对比和分析了 synchronized 和 ReentrantLock,算是专栏进入并发编程阶段的热身,相信你已经对线程安全,以及如何使用基本的同步机制有了基础&#…...
node环境搭建以及接口的封装
node环境搭建 文章目录node环境搭建1.在cmd中输入命令安装express(全局)2.在自己的项目下安装serve3.测试接口4.连接mysql4.1 创建数据表4.2 在serve目录下建db下的sql.js4.3 sql.js4.4 在serve路径下安装mysql4.5 在routes 中引入并发送请求4.6 请求到数…...
跟着我从零开始入门FPGA(一周入门系列)第七天
7、设计一个只有4条指令的CPU我们要设计一个简单的CPU既然做CPU,我们要做流水线的,要简单,做2级流水线就够了。为了实例的简单,我们选择设计一个8bit的MCU的内核仍然我们要简单,所以选择RISC的内核,类似PIC…...
Synopsys Sentaurus TCAD系列教程之--Sde概述
Sde 方便处理rule check相关的问题。同时也能让使用者进一步了解器件结构、掺杂和引线等基本操作。Sde用于搭建结构,重新优化网格,提供.mesh文件供后面Sdevice仿真,主要包含以下几部分: 第一部分: Scheme BasicsDefi…...
计算结构体大小
计算结构体大小 目录计算结构体大小一. 结构体内存对齐1. 简介2. 嵌套结构体二. offsetof三. 内存对齐的意义四. 修改默认对齐数一. 结构体内存对齐 以字节(bety)为单位 1. 简介 对于结构体成员在内存里的存储,存在结构体的对齐规则&#…...
第二十一篇 数据增强
文章目录 摘要1、数据增强的作用2、常用的图像增强方法2.1、一些辅助函数ToTensorToPILImageNormalizeResize2.2、中心裁剪2.3、亮度、对比度和颜色的变化2.4、随机裁剪2.5、随机灰度与灰度2.6、水平/竖直翻转2.6.1、水平翻转2.6.2、垂直旋转2.7、随机角度旋转2.8、随机仿射变换…...
记一次线上es慢查询导致的服务不可用
现象 某日线上业务同学反馈订单列表查询页面一直loding,然后提示请求超时,几分钟之后恢复正常 接到报障之后,马上根据接口URL,定位到了请求链路,发现是es查询超时,这里我们的业务订单表数据是由几百万的&a…...
分布式之ZAB协议
写在前面 假定我们现在使用zk执行了如下的指令: [zk: 192.168.0.10:2181(CONNECTED) 0] create /dongshidaddy 123 Created /dongshidaddy [zk: 192.168.0.10:2181(CONNECTED) 1] create /dongshidaddy/mongo 456 Created /dongshidaddy/mongo假定因为节点故障最终…...
MySQL binlog常用命令及设置清理时间
MySQL binlog常用命令及设置清理时间1 binlog 基本概念2 binlog常用命令3 清理MySQL的binlog日志3.1 自动清理3.2 手动清理文章参考: http://www.360doc.com/content/22/0418/08/65840191_1027038859.shtml https://www.cnblogs.com/kiko2014551511/p/11532426.html…...
Windows下载安装Prometheus
目录 资料 下载 解压 点击prometheus.exe运行 资料 Prometheus是一个开源的系统监控和报警系统,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群。 官网:https://pr…...
0-1背包、完全背包及其变形【零神基础精讲】
来源0x3f:https://space.bilibili.com/206214 三叶姐的对背包问题的总结:【宫水三叶】详解完全背包一维空间优化推导(附背包问题攻略)https://leetcode.cn/circle/discuss/GWpXCM/ 文章目录0-1背包、完全背包及其拓展(…...
OpenStack
OpenStack优势: 1、模块松耦合。 2、组件配置较为灵活。 3、二次开发容易 OpenStack共享服务组件: 1、数据库服务:MongoDB 2、消息列队:RabbitMQ 3、缓存:Redis 4、存储:Ceph 5、负载均衡ÿ…...
Spring Boot整合Kaptcha实现验证码功能
目录一、前言1.Kaptcha 简介2.Kaptcha 详细配置表二、实现1.整合kaptcha,创建kaptcha的工具类1.1 添加依赖1.2 创建KaptchaConfig工具类2 编写接口,在接口中使用 kaptcha 工具类来生成验证码图片(验证码信息)并返回3 登录时从sess…...
【2023】某python语言程序设计跟学第一周内容
本文说明: 案例内容为北理工python语言程序设计课程,如有不妥请联系! 目录温度转换案例:执行结果:代码解析:白话说明:举一反三:根据输入半径求圆周长或面积执行结果:温度…...
C#学习记录——接口的实现
一小部分知识精英依旧直面核心困难,努力地进行深度钻研,生产内容;而大多数信息受众始终在享受轻度学习,消费内容。如果我们真的希望在时代潮流中占据一席之地,那就应该尽早抛弃轻松学习的幻想,锤炼深度学习…...
“ChatGPT之父”Sam Altman:我是如何成功的?
背靠微软,OpenAI能拳打谷歌,脚踢Meta,它背后的男人,必然不简单。 让我们来看一看,Sam Altman是如何一步步成长为今天这个搅动全世界的男人。 山姆奥特曼(Sam Altman) 成长和创业经历 在YC创始…...
jQuery发送Ajax请求的几种方式
概述JQuery发送ajax请求的方法有很多,其中最基本的方法是$.ajax,在其中封装的方法有 $.get, $post等。我们分别举了不同的示例。数据格式首先,浏览器与服务器之间传输数据所采用的格式,比较常见的有json,jsonp…...
网站商城建设的维度/百度知道免费提问
wget:使用yum安装文件之前,要先确定一下/etc/yum.repos.d下的文件是否改变 在使用yum安装wget inotify:yum -y install inotify-tools scp:可以在有scp命令的电脑上查询一下scp的包名 # which scp # rpm -qf /usr/bin/scp scp的安…...
做黑时时彩的网站/seo系统推广
PSpice已经成为模拟电路仿真使用的行业标准工具。模拟电路具有真实的物理实现,可以用它们的原理示意图进行仿真,其频率响应是电路时间常数的结果。与之相反的是,数字滤波器对一系列样本进行数学运算。 数字滤波器的时间常数隐藏在采样间隔T中…...
企业网站客户案例/怎么去做推广
最近在看路由器和交换机的基本知识,发现有连个概念必须弄清楚,否则很容易迷失在错综复杂的网络之中。那就是网络接口和网络交换接口。 网络接口,指的是路由器或PC网卡的外联接口,该接口对内连接着一个具有MAC地址的网络芯片。这种…...
起重机网站怎么做/邯郸网站优化公司
目前,我国已成为全球最大的驾驶培训市场,根据前瞻产业研究院发布相关报告预测,2017年我国机动车驾驶人数量将达到3.95亿人。2017年较上年新增驾驶人数量约3100万人。以人均学车价格5000元来计算,至2017年,我国机动车驾…...
网页前端开发技术/网站是怎么优化推广的
18年国庆,栈长分享了一次我的真实相亲经历:《一个程序员的国庆血泪相亲史,惨败而归…》,大家反响爆蓬。有的现在还在后台留言鼓励我,或者问我有没有找到女朋友之类的,不用担心这事啦,那都是陈年…...
怎么做淘宝客导购网站/渠道推广策略
最近的工程需要搞一下并行,打算用一下cuda。开这个系列希望能够把这个过程中学到的有关并行的知识以及一些问题。 这一次主要介绍下如何在cuda并行中使用vector,包括空间分配与使用。 vector其实是可以被看做一个动态数组的,其存储的分配也…...