目录

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的实现实例分析的文章,可以给我留言哦