前言

元类在python中是很重要的一部分,我将分两次去讲解元类及其应用,此篇为详解元类及其应用第一篇,下面开始今天的说明~~~

1. 类也是对象

在⼤多数编程语⾔中,类就是⼀组⽤来描述如何⽣成⼀个对象的代码段。在 Python中这⼀点仍然成⽴:

>>> class ObjectCreator(object):
… pass

>>>my_object = ObjectCreator()
>>>print(my_object)
<__main__.ObjectCreator object at 0x8974f2c>

但是,Python中的类还远不⽌如此。类同样也是⼀种对象。是的,没错,就是对象。只要你使⽤关键字class,Python解释器在执⾏的时候就会创建⼀个 对象。
下⾯的代码段:

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

将在内存中创建⼀个对象,名字就是ObjectCreator。这个对象(类对象 ObjectCreator)拥有创建对象(实例对象)的能⼒。但是,它的本质仍然是 ⼀个对象,于是乎你可以对它做如下的操作:
1. 你可以将它赋值给⼀个变量

2. 你可以拷⻉它

3. 你可以为它增加属性

4. 你可以将它作为函数参数进⾏传递

下⾯是示例:

>>>    print(ObjectCreator)#你可以打印⼀个类,因为它其实也是⼀个对象
<class '__main__.ObjectCreator'>
>>> def echo(o):
... print(o)
...
>>> echo(ObjectCreator)#你可以将类做为参数传给函数
<class '__main__.ObjectCreator'>
>>> print(hasattr(ObjectCreator,'new_attribute'))
False
>>>ObjectCreator.new_attribute='foo'#你可以为类增加属性
>>>print(hasattr(ObjectCreator, 'new_attribute'))
True
>>>print(ObjectCreator.new_attribute)
foo
>>>ObjectCreatorMirror=ObjectCreator#你可以将类赋值给⼀个变量
>>>print(ObjectCreatorMirror())
<__main__.ObjectCreator object at 0x8997b4c>

2. 动态地创建类

因为类也是对象,你可以在运⾏时动态的创建它们,就像其他任何对象⼀样。⾸先,你可以在函数中创建类,使⽤class关键字即可。

>>> def choose_class(name):
...: if name == 'foo':
...: class Foo(object):
...: pass
...: return Foo #返回的是类,不是类的实例
...: else:
...: class Bar(object):
...: pass
...: return Bar
...:
>>> MyClass=choose_class('foo')
>>> print(MyClass)#函数返回的是类,不是类的实例
<class '__main__.choose_class.<locals>.Foo'>
>>> print(MyClass())#你可以通过这个类创建类实例,也就是对象
<__main__.choose_class.<locals>.Foo object at 0x000001C54F7007B8>

但这还不够动态,因为你仍然需要⾃⼰编写整个类的代码。由于类也是对 象,所以它们必须是通过什么东⻄来⽣成的才对。当你使⽤class关键字时, Python解释器⾃动创建这个对象。但就和Python中的⼤多数事情⼀样, Python仍然提供给你⼿动处理的⽅法。
还记得内建函数type吗?这个古⽼但强⼤的函数能够让你知道⼀个对象的类 型是什么,就像这样:

>>> print(type(1))#数值的类型
<class 'int'>
>>> print(type(""))#字符串的类型
<class 'str'>
>>> print(type(ObjectCreator()))#实例对象的类型
<class '__main__.ObjectCreator'>
>>> print(type(ObjectCreator))#类的类型
<type 'type'>

仔细观察上⾯的运⾏结果,发现使⽤type对ObjectCreator查看类型是,答案 为type, 是不是有些惊讶。。。看下⾯

3. 使⽤type创建类

type还有⼀种完全不同的功能,动态的创建类。
type可以接受⼀个类的描述作为参数,然后返回⼀个类。(要知道,根据传入参数的不同,同⼀个函数拥有两种完全不同的⽤法是⼀件很傻的事情,但 这在Python中是为了保持向后兼容性)
type可以像这样⼯作:
type(类名, 由⽗类名称组成的元组(针对继承的情况,可以为空),包含属 性的字典(名称和值))
⽐如下⾯的代码:

In [7]: class Test:#定义了⼀个Test类
...: pass
...: In [8]: Test()#创建了⼀个Test类的实例对象
Out[8]: <__main__.Test at 0x1c54f648518>

可以⼿动像这样创建:

In [9]: Test2 = type("Test2",(),{})#定义了⼀个Test2类

In [10]: Test2()#创建了⼀个Test2类的实例对象
Out[10]: <__main__.Test2 at 0x1c54f66ed68>

我们使⽤"Test2"作为类名,并且也可以把它当做⼀个变量来作为类的引⽤。 类和变量是不同的,这⾥没有任何理由把事情弄的复杂。即type函数中第1个实参,也可以叫做其他的名字,这个名字表示类的名字

In [11]: MyDogClass = type('MyDog',(),{})

In [12]: print(MyDogClass)
<class '__main__.MyDog'>

使⽤help来测试这2个类

In [13]: help(Test)#⽤help查看Test类
Help on class Test in module __main__: class Test(builtins.object)
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
In [14]: help(Test2)#⽤help查看Test2类
Help on class Test2 in module __main__: class Test2(builtins.object)
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

4.使⽤type创建带有属性的类

type 接受⼀个字典来为类定义属性,因此

In [15]: Foo = type('Foo',(),{'bar':True})

可以翻译为:

In [16]: class Foo(object):
...: bar = True

并且可以将Foo当成⼀个普通的类⼀样使⽤:

In [17]: print(Foo)
<class '__main__.Foo'> In [18]: print(Foo.bar)
True In [19]: f = Foo() In [20]: print(f)
<__main__.Foo object at 0x000001C54F6511D0> In [21]: print(f.bar)
True

当然,你可以向这个类继承,所以,如下的代码:

In [22]: class FooChild(Foo):
...: pass

就可以写成:

In [23]: FooChild = type('FooChild',(Foo,),{})

In [24]: print(FooChild)
<class '__main__.FooChild'> In [25]: print(FooChild.bar)
True

注意:

  • type的第2个参数,元组中是⽗类的名字,⽽不是字符串
  • 添加的属性是类属性,并不是实例属性

【python进阶】详解元类及其应用1的更多相关文章

  1. Python进阶——详解元类,metaclass的原理和用法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题第18篇文章,我们来继续聊聊Python当中的元类. 在上上篇文章当中我们介绍了type元类的用法,在上一篇文章当中我 ...

  2. 【python进阶】详解元类及其应用2

    前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...

  3. Python说文解字_详解元类

    1.深入理解一切接对象: 1.1 什么是类和对象? 首先明白元类之前要明白什么叫做类.类是面向对象object oriented programming的重要概念.在面向对象中类和对象是最基本的两个概 ...

  4. Python进阶开发之元类编程

    系列文章 √第一章 元类编程,已完成 ; 本文目录 类是如何产生的如何使用type创建类理解什么是元类使用元类的意义元类实战:ORM . 类是如何产生的 类是如何产生?这个问题肯定很傻.实则不然,很多 ...

  5. [转] Python Traceback详解

    追莫名其妙的bugs利器-mark- 转自:https://www.jianshu.com/p/a8cb5375171a   Python Traceback详解   刚接触Python的时候,简单的 ...

  6. Python Collections详解

    Python Collections详解 collections模块在内置数据结构(list.tuple.dict.set)的基础上,提供了几个额外的数据结构:ChainMap.Counter.deq ...

  7. python多线程详解

    目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 二.线程实现 threading模块 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 互斥锁 递归锁 信号量 ...

  8. Python数据类型详解——元组

    Python数据类型详解--元组 有时候我们的列表数据不想被别人修改时该怎么办? 此时,就可以使用元组来存放,元祖又称为只读列表,不能修改 定义方式:与列表类似,将列表的[]换成()即可. 特性: 1 ...

  9. 【python】详解事件驱动event实现

    [python]详解事件驱动event实现 所有的计算机程序都可以大致分为两类:脚本型(单次运行)和连续运行型(直到用户主动退出). 1.脚本型:脚本型的程序包括最早的批处理文件以及使用Python做 ...

随机推荐

  1. color 圆盘染色

    Color 圆盘染色 题目大意:给你一个圆盘,等分成n个扇形,有m种颜色,每两个相邻的扇形不能相交,求染色方案数. 注释:m,n<=$10^6$. 想法:这题是小圆盘染色的加强版(小圆盘染色?) ...

  2. selenium2自动化测试学习笔记(三)

    今天是学习selenium的第三天,今天的主题是自动登录126邮箱. 今天总结碰到的坑有三个: 1.frame内元素抓取,使用driver.switch_to.frame(frameId)方法切换锁定 ...

  3. 201621123062《java程序设计》第七周作业总结

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 1.布局管理器的具体使用方法 2.事件处理模型及其代码的编写 3.Swing中的常用组件 4. ...

  4. 关于安装wordpress出现500 Internal Server Error的解决方案

    安装新版本wordpress出现500 Internal Server Error的问题: 在./wp-includes/class-http.php的268行,改成 $request_order = ...

  5. 从同步阻塞聊到Java三种IO方式

    本文总结自 https://zhuanlan.zhihu.com/p/34408883, https://www.zhihu.com/question/19732473中愚抄的回答, http://b ...

  6. JS判断不同操作系统显示不同样式css

    <script type="text/javascript"> var system ={}; var p = navigator.platform; //判断是否为P ...

  7. 关于kali linux 2.0的vmware tools的安装问题

    在安装好kali linux 2.0 后,首先要做的就是添加源并更新系统,否则会出现软件定位问题. 在kali 2.0中,vmware tools已经不能使用了,官方放了一个工具下载安装就好. 添加源 ...

  8. WIN10系统触摸板快捷键

    快捷的手势操作,有时候会让人脱离鼠标,只要不是非用不可的情况,基本上这些常用手势就能让我们摆脱鼠标携带不便或者桌子地方小的烦恼.iOS上的快捷手势很是受欢迎,win10上却鲜有人知晓,尤其是非开发人员 ...

  9. Postgres中postmaster代码解析(上)

    之前我的一些文章都是在说Postgres的一些查询相关的代码.但是对于Postgres服务端是如何启动,后台进程是如何加载,服务端在哪里以及如何监听客户端的连接都没有一个清晰的逻辑.那么今天我来说说P ...

  10. JMeter入门(01)概念和样例

    一.概念 JMeter 是一款专门用于功能测试和压力测试的轻量级测试开发平台,实现了许多和互联网相关的网络测试组件,同时还保留着很强的扩展性. JMeter可以用来测试诸如:静态文件,Java Ser ...