前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进阶必看:python元类编程

进阶必看:python元类编程

作者头像
make a bug
发布2022-09-20 14:59:31
5970
发布2022-09-20 14:59:31
举报
文章被收录于专栏:我和bug只能活一个

元类编程

在介绍元类编程前,我们先回顾下前面的内容,在之前的文章我们有了解过python的面对对象编程的基本实现机制就是魔法函数,而在python3中,新型类统一了类和类型的概念。所有的类都是type的实例包括type自身也是自己的实例,除object之外其他类都继承object。

如上图

动态创建类

由所有类的实例都为type可以得到如下结论

class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。

type()函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过type()函数创建出Hello类,而无需通过class Hello(object)...的定义,如下图的例子

直接用type创建一个类而不是写Class

type是python多态的体现

通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。

正常情况下,我们都用class Xxx...来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。

metaclass

metaclass 直译过来就是元类

简单的解释就是:

当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。

但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类就是元类编程。

Perseverance Prevails

metaclass是Python面向对象里最难理解,也是最难使用的魔术代码。正常情况下,你不会碰到需要使用metaclass的情况,所以,以下内容看不懂也没关系,因为基本上你不会用到。但是如果你是进阶,还是了解一下,和抽象是息息相关的。

上图是网上找来的一个栗子

当我们传入关键字参数metaclass时,魔术就生效了,它指示Python解释器在创建MyList时,要通过ListMetaclass.__new__()来创建。这个方法中的MyList是由add方法的,但是普通的python自带的list是没有这个方法的。

思考:动态修改有什么意义?直接在MyList定义中写上add()方法不是更简单吗?正常情况下,确实应该直接写,通过metaclass不太符合常理。

一个单例模式

元类使类的创建行为发生了改变,当用户定义一个class Logger()时,Python解释器首先在当前类Logger的定义中查找metaclass,找到了,就使用Logger中定义的metaclass的SingletonMetaThreadSafe来创建Logger类,也就是说,metaclass可以隐式地继承到子类,但子类自己却感觉不到,换一句话,元类里的方法优先级最高,所以说,它改变了类创建的行为,是很危险的,一般不推荐使用。

我们讲了这么多,肯定不会只得到不推荐使用的结论,毕竟,存在即合理。

就元类本身而言,它的作用是:

1.拦截类的创建

2.修改类

3.返回修改之后的类

使用元类还是有一些好处的:

1.意图更加明确。当然你的metaclass名字要起好

2.面向对象。可以隐式继承到子类

3.可以更好地组织代码

可以用__new__,__init__,__call__等方法更好地控制。

回到例子本身思考

这个单例模式的栗子已经说明了它的优点。如果我想做个线程安全的日志,我可以把获取锁的操作单独加在logger中,那如果我们又要写一个线程安全的缓存呢,是不是也要加锁在缓存类。由此,我们可以抽象出一个很重要的基类用来控制线程安全,也就是加一个锁,并且这个基类中的一些行为方法,比如基类中的__call的优先级是最高的,它就拦截了logger实例的创建,那么日志中再写call就会被覆盖掉,更能保证线程的安全。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI懒人星球 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档