本文主要是介绍python基础知识(26)元类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、Python 中类也是对象
在了解元类之前,我们先进一步理解 Python 中的类,在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段。在 Python 中这一点也是一样的。
这点在学习类的章节也强调过了,下面可以通过例子回忆一下:
class ObjectCreator(object):passmObject = ObjectCreator() print(mObject)
输出结果:
<__main__.ObjectCreator object at 0x00000000023EE048>
但是,Python 中的类有一点跟大多数的编程语言不同,在 Python 中,可以把类理解成也是一种对象。对的,这里没有写错,就是对象。
为什么呢?
因为只要使用关键字 class
,Python 解释器在执行的时候就会创建一个对象。
如:
class ObjectCreator(object):pass
当程序运行这段代码的时候,就会在内存中创建一个对象,名字就是ObjectCreator。这个对象(类)自身拥有创建对象(类实例)的能力,而这就是为什么它是一个类的原因。
但是,它的本质仍然是一个对象,于是我们可以对它做如下的操作:
class ObjectCreator(object):passdef echo(ob):print(ob)mObject = ObjectCreator() print(mObject)# 可以直接打印一个类,因为它其实也是一个对象 print(ObjectCreator) # 可以直接把一个类作为参数传给函数(注意这里是类,是没有实例化的) echo(ObjectCreator) # 也可以直接把类赋值给一个变量 objectCreator = ObjectCreator print(objectCreator)
输出的结果如下:
<__main__.ObjectCreator object at 0x000000000240E358>
<class '__main__.ObjectCreator'>
<class '__main__.ObjectCreator'>
<class '__main__.ObjectCreator'>
二、使用 type()
动态创建类
因为类也是对象,所以我们可以在程序运行的时候创建类。
Python 是动态语言。
动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。
在之前,我们先了了解下 type()
函数。
首先我们新建一个 hello.py
的模块,然后定义一个 Hello 的 class ,
class Hello(object):def hello(self, name='Py'):print('Hello,', name)
然后在另一个模块中引用 hello 模块,并输出相应的信息。
其中 type()
函数的作用是可以查看一个类型和变量的类型。
#!/usr/bin/env python3 # -*- coding: UTF-8 -*-from com.twowater.hello import Helloh = Hello() h.hello()print(type(Hello)) print(type(h))
输出的结果是怎样的呢?
Hello, Py
<class 'type'>
<class 'com.twowater.hello.Hello'>
上面也提到过,type()
函数可以查看一个类型或变量的类型,Hello
是一个 class
,它的类型就是 type
,而 h
是一个实例,它的类型就是 com.twowater.hello.Hello
。
前面的 com.twowater
是我的包名,hello
模块在该包名下。
在这里还要细想一下,上面的例子中,我们使用 type()
函数查看一个类型或者变量的类型。
其中查看了一个 Hello
class 的类型,打印的结果是: <class 'type'>
。
其实 type()
函数不仅可以返回一个对象的类型,也可以创建出新的类型。
class 的定义是运行时动态创建的,而创建 class 的方法就是使用 type()
函数。
比如我们可以通过 type()
函数创建出上面例子中的 Hello
类,具体看下面的代码:
# -*- coding: UTF-8 -*-def printHello(self, name='Py'):# 定义一个打印 Hello 的函数print('Hello,', name)# 创建一个 Hello 类 Hello = type('Hello', (object,), dict(hello=printHello))# 实例化 Hello 类 h = Hello() # 调用 Hello 类的方法 h.hello() # 查看 Hello class 的类型 print(type(Hello)) # 查看实例 h 的类型 print(type(h))
输出的结果如下:
Hello, Py
<class 'type'>
<class '__main__.Hello'>
在这里,需先了解下通过 type()
函数创建 class 对象的参数说明:
1、class 的名称,比如例子中的起名为 Hello
2、继承的父类集合,注意 Python 支持多重继承,如果只有一个父类,tuple 要使用单元素写法;例子中继承 object 类,因为是单元素的 tuple ,所以写成 (object,)
3、class 的方法名称与函数绑定;例子中将函数 printHello
绑定在方法名 hello
中
具体的模式如下:
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
好了,了解完具体的参数使用之外,我们看看输出的结果,可以看到,通过 type()
函数创建的类和直接写 class 是完全一样的。
这是因为Python 解释器遇到 class 定义时,仅仅是扫描一下 class 定义的语法,然后调用 type()
函数创建出 class 的。
不过一般的情况下,我们都是使用 class ***...
的方法来定义类的,不过 type()
函数也可以让我们创建出类来。
也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。
可以看到,在 Python 中,类也是对象,你可以动态的创建类。
其实这也就是当你使用关键字 class 时 Python 在幕后做的事情,而这就是通过元类来实现的。
这篇关于python基础知识(26)元类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!