python 什么是原类_Python 什么是元类(metaclasses)?

1.什么是类

在理解元类之前,我们必须先掌握Python中的类(class)。

和大多数语言一样,Python中的类知识用来描述如何“生成一个对象”:

8c9c532a-0949-42bf-9a21-833c7b247338.png

但是,在Python中,类不仅能用来描述如何生成一个对象,类本身也是对象。

在你使用关键词 class 的时候,Python就会执行它,并创建一个对象。

>>> class ObjectCreator(object):... pass...

上述指令在内存中创建了一个“ObjectiveCreator”的对象。

这个对象(类)本身具有创建对象(实例)的能力,因此它也是一个类。你可以对它做以下操作:

1.将其分配给变量

2.复制它

3.为其添加属性

4.将其作为函数参数传递

例如:

6cbc7706-4f54-4b56-9299-49b6fff3d901.png

2.动态创建类

由于类是对象,因此你可以像创建任何对象(数组、字典等)一样,随时随地创建类。

你甚至可以在函数里创建类:

072e301b-4d05-48ee-af77-449aa8fdf5fd.png

郑州哪里的妇科医院好http://www.zztjfk.com/

郑州妇科医院哪里好http://www.zzyytj.com/

但是,这样的类并不是很动态,因为你必须自己编写整个类。

使用class关键字时,Python会帮你自动创建此对象,但是,Python同样也提供了一种手动创建的方法,那就是type函数。

>>> print(type(1))>>> print(type("1"))>>> print(type(ObjectCreator))>>> print(type(ObjectCreator()))

type函数最经典的用法是返回对象的类型。但是很少人知道,它还能接受参数并手动创建类。

type(name, bases, attrs)

其中

name: 类名

bases: 元组,父类名

attrs: 字典,类属性值

因此你可以这样手动创建类:

>>> MyShinyClass = type('MyShinyClass', (), {}) # returns a class object>>> print(MyShinyClass)>>> print(MyShinyClass()) # create an instance with the class<__main__.MyShinyClass object at 0x8997cec>

如果你想给它赋予属性,可以这样玩:

>>> class Foo(object):... bar = True

等同于

>>> Foo = type('Foo', (), {'bar':True})

用来继承也是可以的:

>>> FooChild = type('FooChild', (Foo,), {})>>> print(FooChild)>>> print(FooChild.bar) # bar is inherited from FooTrue

可见通过 type() 函数创建的类和直接写class是完全一样的。

因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用 type() 函数创建出class。

正常情况下,我们用class来定义类,但是,type()函数也允许我们动态创建类,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同。

Python是通过什么做到这一切的?那就是元类。

3.什么是元类

元类就是用于创建类的“东西”。

你定义类是为了创建对象,Python中所有的类都是对象。元类是用于创建这些对象的。可以看这个例子:

MyClass = MetaClass()my_object = MyClass()

这有点像套娃。这段代码转化为type就是这样的:

MyClass = type('MyClass', (), {})

因此,我们可以得到一个基本事实,type 本身就是一个元类。

其实,就是 type 在幕后创建了Python中所有的类。

通过检查__class__属性,你会看到Python中,一切对象都是基于 type 的:

>>> age = 35>>> age.__class__>>> name = 'bob'>>> name.__class__>>> def foo(): pass>>> foo.__class__>>> class Bar(object): pass>>> b = Bar()>>> b.__class__

那么,有个有趣的问题,__class__的__class__是什么呢?

>>> age.__class__.__class__>>> name.__class__.__class__>>> foo.__class__.__class__>>> b.__class__.__class__

因此,元类只是创建类对象的东西,如果愿意,可以将其称为“类的工厂”。

type 是Python使用的内置元类。不过,你可以创建自己的元类。

3.1 __metaclass__属性

在Python 2中,可以在编写类时添加属性__metaclass__,使用某个元类来创建该类:

class Foo(object): __metaclass__ = something... [...]

不过要小心的是,你虽然先写了 class Foo(object),但Foo这个对象尚未被创建,Python将先寻找__metaclass__类,找到后用它来创建Foo类。

如果没有这个__metaclass__类,它将使用 type 来创建类。

因此,类创建的流程是这样的:

1.创建的类中有__metaclass__元类属性吗?

2.如果有,那就用__metaclass__给该类在内存中创建一个类对象。

3.如果Python找不到__metaclass__,它将在MODULE级别查找__metaclass__属性 。

4.如果还是没有,那就使用父类的元类来创建类对象。

现在的问题就是,你可以在__metaclass__中放置些什么代码呢?

答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢?type,或者任何继承或使用它的东西。

3.2 Python 3中的元类

设置元类的语法在Python3已改为:

class Foo(object, metaclass=something): ...

即不再使用__metaclass__属性,而是在基类参数列表中引入关键字参数。

不过元类的基本工作方式不变。在Python3中,你可以将属性作为关键字参数传递给元类:

class Foo(object, metaclass=something, kwarg1=value1, kwarg2=value2): ...

4.为什么需要元类

元类最主要的一个应用方向是创建API,一个最著名的应用是Django ORM,比如:

class Person(models.Model): name = models.CharField(max_length=30) age = models.IntegerField()

当你这样访问属性的时候:

person = Person(name='bob', age='35')print(person.age)

它并不会返回models.IntegerField,而是返回了一个整形的数字。

这是因为models.Model引用了一个ModelBase类,该类随后进行了魔术般地操作,使其能够与数据库字段进行挂钩。

这就是元类的作用,Django通过它,完成了系列复杂的幕后工作,将原本非常复杂的事情变得非常简单。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

听说这是和女朋友住一起后的现象之一

1 被人叫醒时的你&#xff01;2 分享一只软糯香甜的香蕉。。3 到底选哪根好呢&#xff1f;4 大叔你的手机壳怎么肥四&#xff1f;&#xff1f;5 听说这是和女朋友住一起后的现象之一6 爱国主义教育培养了一群吃货&#xff01;7 今天做做题吧&#xff01;&#xff08;本视频来源…

PDF 补丁丁 (修改PDF书签;拆分、合并、制作PDF;提取图片) 0.3.0.8 正式版

PDF 补丁丁 0.3.0.8 正式版 新版本已经发布&#xff0c;请到博客首页下载。 软件简介 PDF补丁丁是一个用于修改PDF文件信息的工具。它具有以下功能&#xff1a;■ 修改文档&#xff08;带“*”号部分功能需通过高级补丁修改功能实现&#xff09;&#xff1a; ● 修改文档属性…

Dapr + .NET 实战(八)服务监测

服务监测分布式服务性能指标&#xff0c;链路追踪&#xff0c;运行状况&#xff0c;日志记录都很重要&#xff0c;我们日常开发中为了实现这些功能需要集成很多功能&#xff0c;替换监控组件时成本也很高。Dapr 可观测性模块将服务监测与应用程序分离。它自动捕获由 Dapr sidec…

世界上第一位程序员是位美女——AdaLovelace【有图为证】

AdaLovelace画像 仙女一般吧....简介&#xff1a; 阿达奥古斯塔&#xff0c;19世纪诗人拜伦的女儿&#xff0c;数学家。穿孔机程序创始人&#xff0c;建立了循环和子程序概念。为计算程序拟定“算法”&#xff0c;写作的第一份“程序设计流程图”&#xff0c;被珍视为“第一个…

php mysql管理_MySQL 连接与管理

让 PHP 支持 MySQLPHP 有专有的 MySQL 函数库以使用操作 MYSQL 数据库。在 PHP 5 及以后版本中不再默认支持 MySQL &#xff0c;所以在运行这些库之前&#xff0c;请确定 php.ini 加载了 MySQL 数据库支持&#xff1a;extension mysql.dllMySQL 连接mysql_connect() 函数用于开…

android开发我的新浪微博客户端-用户授权页面UI篇(3.1)

上一篇讲了讲OAuth授权认证的事情,大概的介绍了OAuth的原理&#xff0c;并且完成了一个OAuth.java的类库&#xff0c;提供了几个OAuth认证必要的方法&#xff0c;本篇开始具体讲本项目的用户授权功能&#xff0c;用户授权页面是当用户第一次使用本软件的时候自动从载入页面跳转…

还缺30万人!程序员2020年要过好日子了……

全世界只有3.14 % 的人关注了爆炸吧知识最近&#xff0c;程序员届有一个重大好消息&#xff0c;可能很多人还不知道&#xff0c;那就是&#xff1a;国内某些城市已经开始程序员人才补贴了&#xff01;对于人工智能公司的项目开发、人才引进、科技研发&#xff0c;最高按照国拨经…

iNeuOS工业互联网操作系统部署在华为欧拉(openEuler)国产系统

目 录1. 概述... 32. 创建虚拟机&安装华为欧拉&#xff08;openEuler&#xff09;系统... 42.1 创建新的虚拟机... 42.2 默认选择Wowrkstation 16.x. 52.3 选择稍后安装操作系统... 62.4 选择其他Liunx 4.x 64位.…

datatables 一列显示两个字段的数据_【tableau入门教程16】计算字段

有时数据表中的原始维度和度量并不满足我们的需求&#xff0c;因此可通过计算字段功能&#xff0c;利用各种函数新建字段。创建字段步骤1、在侧栏 创建计算字段2、拖曳字段到输入框或是输入部分字段名称选择字段&#xff0c;当输入框下面显示“计算有效”时可点击 确定 完成计算…

gcc 安装包_LNMP安装的前期准备(LNMP一键安装包下载)

如果我们手工安装 LNMP 环境&#xff0c;那么同样需要安装大概 14 个源码包(根据版本和功能不同而不同)。不过&#xff0c;现在网上非常流行的 LNMP 环境的搭建过程是采用 LNMP 一键安装包直接安装。这个一键安装包实际上就是一个事先写好的安装脚本&#xff0c;按照这个安装脚…

Dapr + .NET 实战(七)Secrets

什么是Secrets应用程序通常会通过使用专用的存储来存储敏感信息&#xff0c;如连接字符串、密钥等。通常这需要建立一个密钥存储&#xff0c;如Azure Key Vault、Hashicorp等&#xff0c;并在那里存储应用程序级别的密钥。要访问这些密钥存储&#xff0c;应用程序需要导入密钥存…

只有成年人才懂的“爽”,一定要安利给每一个人

▲ 点击查看在日常生活中&#xff0c;诸位是不是经常遇到这些问题&#xff1a;打球扭伤、骑车摔伤、跑步拉伤、户外受伤。或者经常伏案工作&#xff0c;一天上班下来&#xff0c;感觉肩膀酸痛到僵硬&#xff0c;对什么事都提不起兴趣。回到家腰酸、背疼&#xff0c;随便做个伸展…

xml.query() 实例演示

xml.query()函数&#xff0c;XQuery表达式可以返回xml一个单一的元素或是所有元素。 我们继续使用上一篇所创建表[dbo].[tbDevLanguage] http://www.cnblogs.com/insus/archive/2012/02/25/2367668.html 首先我们演示Query所有元素&#xff0c;注意一下查询节点&#xff0c;返回…

图像处理前沿技术_深入浅出人工智能前沿技术—机器视觉检测,看清人类智慧工业...

早在50年前&#xff0c;工业机器人就已经横空出世&#xff0c;给人类带来更多的方便与可能。今天&#xff0c;工业机器人正以迅猛的发展速度替代人工&#xff0c;从事繁重及枯燥的工作&#xff0c;并且向着更智能的方向在发展&#xff0c;而服务机器人&#xff0c;将会是下一个…

最全高考分数线出炉!!查了分后,这届学生为了过线真是太拼了.......

全世界只有3.14 % 的人关注了爆炸吧知识2020年高考成绩今天可以查了&#xff01;你还记得自己查分那天是什么心情吗&#xff1f;反正超模君当年是想看却又不敢看表面越是想要云淡风轻内心就越不受控制的心跳失控转眼过去了许多年又到了高考放榜的日子在这么欢乐的日子里怎么能缺…

学习笔记之web worker

当在 HTML 页面中执行脚本时&#xff0c;页面的状态是不可响应的&#xff0c;直到脚本已完成。web worker 是运行在后台的 JavaScript&#xff0c;独立于其他脚本&#xff0c;不会影响页面的性能。您可以继续做任何愿意做的事情&#xff1a;点击、选取内容等等&#xff0c;而此…

让人难以置信的HTML5和JavaScript实验

Google的 Chrome实验室收集了很多让人难以置信的基于 HTML5 Canvas 和 JavaScript 的实验项目&#xff0c;里面的例子都很独特&#xff0c;让人惊叹。我从未想过结合 HTML 和 JavaScript 能实现这么强大的效果。今天&#xff0c;本文与大家分享其中9个很棒的例子&#xff0c;为…

22468!Windows 11新预览版发布:旧版系统支持十月终止请速升

面向 Dev 频道的 Windows 预览体验成员&#xff0c;微软现已发布 Windows 11 预览版 Build 22468。Windows 11 Insider Preview Build 22468 主要变化如下&#xff1a;1.此前 Dev 频道推送的所有 Windows 11 预览版将于 2021 年 10 月 31 日到期&#xff0c;请立即更新到 Windo…

influxdb mysql对比_InfluxDB和MySQL的读写对比测试

今天进行了InfluxDB和MySQL的读写对比测试&#xff0c;这里记录下结果&#xff0c;也方便我以后查阅。操作系统&#xff1a; CentOS6.5_x64InfluxDB版本 &#xff1a; v1.1.0MySQL版本&#xff1a;v5.1.73CPU &#xff1a; Intel(R) Core(TM) i5-2320 CPU 3.00GHz内存 &#x…

Zabbix Maintenance 维护周期

为什么80%的码农都做不了架构师&#xff1f;>>> 概述 你可以定义维护周期在主机或主机组里。这里有2种维护状态&#xff0c;一种是停止对目标的监控数据的收集&#xff0c;一种是继续对目标的监控数据的收集。 当不想收到维护中的服务器的报警时候&#xff0c;需…