一文读懂什么是元类

元类

要了解元类,首先我们要知道类是什么,而类是面向对象中一种重要的集合。一般开发的思路可以分为面向对象(OOP)和面向过程,请参考上一篇推文 什么是对象和OOP!

动态语言

首先我们知道python是一个动态语言,和静态语言不同的是,静态语言在编译过程就会把你的脚本编译完成,而动态语言是当你使用时候才会动态的执行你的脚本,而python就是这样一种语言

type

type是python的一个内建模块,python动态创建类的方法就是使用到了type()函数,也可以用作查看对象类型的函数

def say_hello():
    print('Hello World!')

h1 = type('Hello', (), {'hello': say_hello})
>>> h1.hello()
Hello World!

class Hello(object):
    def say_hello(self):
        print('Hello World!')
h2 = Hello()
>>> h2.say_hello()
Hello World!

这里我们可以看出,通过type动态去创建和定义class实例化在调用是一样的效果,我们要注意:创建类的时候实际就是调用了type去完成

创建一个类,type给的定义是:

Init signature: type(self, /, *args, **kwargs)
Docstring:
type(object_or_name, bases, dict)
type(object) -> the object’s type
type(name, bases, dict) -> a new type

需要依次传入类名、继承的父类集合、方法或者属性的绑定,上面的例子我们绑定了一个say_hello方法

metaclass

创建类之外,我们可以通过metaclass控制创建行为,也称其为元类,简单的解释就是类的类

一般我们先定义类,之后可以实例创建出对象;那我们想要创建类就需要先定义metaclass,然后创建类,所以我们定义一个类,python会调用父类直到object模块的metaclass来创建类。这里可以理解为,你定义的,是metaclass的一个实例

元类的作用

元类可以做什么呢,通俗的说,在编程实现某些逻辑的时候,我们需要对其进行先验处理和拦截,甚至在这上面做一些统一的操作,你可能会说,那我们直接写一个父类继承不就可以了吗?是的,不过元类的存在是更加深层次的概念。

1、我们以前端的拦截器举例,当你想对请求或者是渲染、装饰等等,我们可能处理的内容不一样,但我们可能都需要做同一件事情,而我们的对象不太统一,这时候可以做一个全局的拦截处理,有点类似于预处理和返回的校验(这里拿前端的距离可能有点不贴切,但是作用类似)

2、用python来举例,在python中我们知道万物皆对象,那你可能会说我们直接用继承的方式。这里可能会有一些理解上的不同。这里举一个通用的例子,数据库ORM1,我们常常写一个数据库Module,需要继承ORM库给到的基类Module,下面先看一个例子讲解2

# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建对象的基类:
Base = declarative_base()

# 定义User对象:
class User(Base):
    # 表的名字:
    __tablename__ = 'user'

    # 表的结构:
    id = Column(String(20), primary_key=True)
    name = Column(String(20))

# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')

# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)

# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()

这里的Base就是对象的基类,这里的Base是sqlalchemy里面可以使用元类来和数据库进行交互,提供API出来,对于使用的用户来说是非常便捷的,但是对于编写的时候会比较复杂。这里可以看出来我们创建一个用户名为Bob的用户只需要简单的一行就可以了。

这里主要是讲解我们说明一下Metaclass的使用,而当你不知道元类的时候,就无需使用它,由于其可以控制类创建的行为,当你无意间写了一些误操作是非常难DeBug的。最后引用一位名人的话术,当我们自然而然的在开发的时候用上,就是真正掌握的时候了

“Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t.”

– Tim Peters

参考链接:


  1. http://www.ruanyifeng.com/blog/2019/02/orm-tutorial.html - ORM详解 ↩︎

  2. https://www.liaoxuefeng.com/wiki/1016959663602400/1017592449371072 - 廖雪峰关于元类的讲解 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值