1.什么是类

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

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

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

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

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

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

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

1.将其分配给变量

2.复制它

3.为其添加属性

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

例如:

2.动态创建类

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

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

郑州哪里的妇科医院好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通过它,完成了系列复杂的幕后工作,将原本非常复杂的事情变得非常简单。

python 什么是原类_Python 什么是元类(metaclasses)?相关推荐

  1. python中的元类_python中的元类

    类也是对象,但是类有创建对象的能力 动态创建一个类: classmonkey():defbanana(self):print 'banana!' defapple(self):print 'i wan ...

  2. python元类_python中的元类 metaclass

    python中的元类 metaclass 在python中,类(class)本身也是一个实例对象, 它的类型则是元类, 如果没有指明, 则自定义类的类型是type. 换言之, 我们所定义的普通类都是t ...

  3. python中的元类_Python中的元类(metaclass)

    提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自身有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理 ...

  4. python的抽象类详解_Python抽象类以及元类

    抽象基类: 继承的约束与协议 __doc__ = """ 抽象基类: 继承的约束与协议 # 抽象基类 --- 有点java的味道,也有点golang的味道,继承,协议,接 ...

  5. python元类_Python基础:元类

    一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯面向对象 的.与那些仅在语法层面声称纯OO的编程语言(如Java)相比,Python的这种纯粹性更加深入骨髓. 在Python的世界 ...

  6. python元类的概念_Python中的元类编程 | 学步园

    过去有这样的概念,一直没有深究它的意义.今天同事问到,刚好也好好了解下. #===============================================Python中的元类编程=== ...

  7. 编写python程序、创建名为class的数据库_Python中的元类(metaclass)以及元类实现单例模式...

    一.理解类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在P ...

  8. python元类单例_python面向对象和元类的理解

    1 python类对象与实例对象 python中一切皆对象(广义上的对象),类也不例外,我们可以称类为类对象.python中内建函数type()可以返回对象的类型,例如type(int)会得到返回值, ...

  9. python简单代码演示效果-演示python如何创建和使用一个简单的元类的代码

    在做工程闲暇时间,将做工程过程比较重要的一些内容备份一下,如下内容段是关于演示python如何创建和使用一个简单的元类的内容,应该能对小伙伴们也有用途. #!/usr/bin/env python # ...

最新文章

  1. JS根据两点的经纬度坐标得到驾车行驶距离
  2. 替换证件照背景颜色仅需十行Python代码
  3. 谷歌发布史上最强人类大脑「地图」,1.3亿个突触,在线可视3D神经元「森林」!...
  4. Java中break、Continue、reutrn总结
  5. ajax实现多选 radio true,jQuery操作radio、checkbox、select的方法总结
  6. linux下拒绝用户登录,Linux系统用户管理之禁止用户登录
  7. Angular4 组件通讯方法大全
  8. python按日期排序_python按修改时间顺序排列文件的实例代码
  9. Python帮你识破双11的套路
  10. AT3913-XOR Tree【状压dp】
  11. TCP/UDP通信解疑
  12. 适用于ActiveX v18.6 x86的Codejock Xtreme Suite Pro
  13. python 时间曲线相似度计算_时间序列相似性度量综述
  14. Arduino小白的学习历程
  15. 对比测评3款BI分析⼯具,还是它最香!
  16. docker: error pulling image configuration
  17. for循环的几种写法
  18. 病原微生物高通量测序:第三节 检测原理
  19. Web前端开发学习笔记(2)(css3新特性)
  20. html可以自学吗,javascript可以自学吗?

热门文章

  1. 代码编辑器横评:为什么 VS Code 能拔得头筹
  2. 从ASP.NET Core2.2到3.0你可能会遇到这些问题
  3. ASP.NET Core 项目简单实现身份验证及鉴权
  4. 让 .Net 更方便的导入导出Excel
  5. asp.net core 外部认证多站点模式实现
  6. docker 开启命令\退出容器
  7. 用matlab求解工作时间调度问题,置换流水车间调度问题的MATLAB求解.doc
  8. 【错误异常大全】:ArcGIS Engine中C#无法引用ESRI.ArcGIS.AxControls问题
  9. 【ArcGIS风暴】ArcGIS添加超链接的两种方法详解
  10. DateTime.Now.Ticks.ToString()说明