Python元类学习笔记
目录
一、前言:
- 作为一名Python语言使用者,可能你会经常看到Python元类、Python元编程等字眼。
- 元编程也被称为Python中的的黑魔法。
- 究竟什么是元编程呢?其又能为卫门带来什么好处而被如此重视呢?
- 带着这些疑问我们一起来学习Python中元编程。
二、概念学习:
- Python中存在一个称为元类的东东,而使用元类来编程也就被称为元编程了。
- 在我接触Python之初,我在网上共享了自己的学习文章,突然有一天,有个小伙伴跟我说,你后面可以分享下元编程相关的知识么?当时我是一脸懵逼的,虽然我接触过的编程语言不少,Python是我最近新入手的语言,但是对于Python的元编程我还没又接触。
- 听到这话话,第一时间当然是先百度一下,我了解过元类,当时觉得Python元编程因为跟其有关,果不其然,百度后验证了我的猜测。
- Python的元编程利用了Python这一动态脚本语言的特性,在对象的创建时为对象增加额外的能力。利用此行为的编程便被大家称为元编程了。
三、使用元类
-
在学习元类之前,我们先来看一个小demo:
-
代码如下:
class Hello: pass h = Hello(); print(h) print(type(h)) print(type(Hello))
-
结果输出为:
<__main__.Hello object at 0x1056c4588> <class '__main__.Hello'> <class 'type'>
-
我们可以看到,我们的h是一个对象
-
我们用type函数打印其类型时,h属于
__main__.Hello
类型,而Hello属于type类型。 -
大家都知道,我们的python是一个动态语言,类都是运行时创建的。
-
我们可以用type输出相关类的类型,其实我们也可以用type来动态的创建类哦。
-
在Python中类的实例,也就是创建出来的对象,其类型是对应的类,而类,在python中其实也是一种类型,类的类型为type。类,其实也是动态创建出来的。
type函数参数解析:
- 要创建一个class对象,type()函数依次传入3个参数:
1、class的名称,参数类型为string; 2、继承的父类集合,参数类型为tuple; 3、一个字典,存储方法名称与方法的映射关系。
-
Ok,我们来动态创建我们的Hello类
def my_fun(self): print('Say hello') Hello1 = type('Hello1',(object,),dict(say_hello=my_fun)) print(Hello1) h1 = Hello1(); h1.say_hello();
-
结果输出为:
<class '__main__.Hello1'> Say hello
四、 metaclass 元类
- 一般情况下,我们不会通过type来动态的创建类,
- metaclass允许我们创建类或者修改类。
- 你可以把类看成是metaclass创建出来的实例。
- 代码修改:
定义一个元类
-
代码如下:
class HelloMetaclass(type): def fn(self): print('Hello!'); def __new__(cls, name, bases, attrs): attrs['say_hello'] = lambda self,name: print('Hello,%s'%name); return super(HelloMetaclass,cls).__new__(cls, name, bases, attrs);
通过制定元类来定义类
-
代码如下:
class Hello(object,metaclass=HelloMetaclass): pass;
普通类定义法
-
代码如下:
class Hello1: def say_hello(self,name): print('Hello,%s !'%name); print(type(Hello)) h = Hello(); h.say_hello('Hello'); print(type(Hello1)) h1 = Hello1(); h1.say_hello('Hello1');
-
结果输出为:
<class '__main__.HelloMetaclass'> Hello,Hello <class 'type'> Hello,Hello1 !
-
可以看到,我们的Hello类的元类为HelloMetaclass。虽然没有定义say_hello方法,但是也可以调用,因为其在创建类时动态添加类say_hello方法,而且其type输出值也是不同的哦。
-
这里我们只是简单举例来了解元编程的威力。
五、元类的使用场景
- 最典型的就是ORM,也就是我们的面向对象的数据库管理框架。
- 构建思路:
- 1、创建一个ModeMetaclass元类,增加特性:1、获取类名,将其作为表名 2、获取对应的字段和对应类型,在创建数据库时使用
- 2、创建一个Mode类,后面要存储的实体类继承自Mode,增加特性:如add,delete,update,remove等基本api。
- 3、实体类继承自Mode类,创建实例即可调用
- 如果有小伙伴需要ORM的实现实例分析的文章,可以给我留言哦