metaclass(元类)的小探索

1.python 的metaclass

关于元类 在python中,有一经典解释文章,特别是注意到,而python中的基本元类就是type,type会根据传入参数的个数来决定发挥打印类型的函数功能或者发挥元类的作用。元类的自定义使用__metaclass__:

(一)自定义metaclass

使用metaclass只需声明:

__metaclass__ = something..

  放置元类的位置可以是任意的,python解释器进行查找元类的顺序这篇文章中已经详细说明:“如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。”值得注意的是,放置位置带来的区别。

放置于:模块级(module level)、类级(class level)、子类或者父类中。。<稍后讲到>

那么作为创建类的类(类工厂),metaclass可以是哪些“东西”呢?

  1. 函数作为metaclass
  2. 类作为metaclass

1).定义函数做为metaclass的情况:

def metafunc(classname,bases,attrs):
    for key,value in attrs.items():
            if isinstance(value,int):
                attrs[key.upper()]=value
                attrs.pop(key)
    print ‘In[%s:From-->%s]‘%(classname,bases)
    return type(classname,bases,attrs)

函数metafunc是定义好的作为__metaclass__元类属性的函数,其作用便是将要创建的类中的int类型的属性名大写。其实也就是在类创建前“做些事”之后,再利用type创建想要的类。值得注意的是:

 1 #此时如果将元类属性放置在module level,发现无任何作用,不知道是不是python版本不同导致
 2 __metaclass__ = metafunc
 3 class MyClass(object):
 4     lower = 123
 5     strs = ‘string in MyClass..‘
 6 class MySubClass(MyClass):
 7     kid_lower = 456
 8     kid_strs = ‘string in MySubClass..‘
 9 #此时若把元类属性放置于父类MyClass或者子类MySubClass中,发现只有放置了__metaclass__属性的类会达到预期的效果
10 class MyClass(object):
11     __metaclass__ = metafunc
12     lower = 123
13     strs = ‘string in MyClass..‘
14 class MySubClass(MyClass):
15     __metaclass__ = metafunc
16     kid_lower = 456
17     kid_strs = ‘string in MySubClass..‘

若将__metaclass__只放置于父类MyClass中,子类并不会被影响...这个不知为何,得同时写进类里<环境:python 2.7.11 in win7 64bits>

【输出:】

放置于父类结果:

In[MyClass:From-->(<type ‘object‘>,)]

放置于子类的结果:

In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]

2).定义类做为metaclass的情况:

class testMetaclass(type):
    def __new__(cls,name,bases,attrs):
        for key,value in attrs.items():
            if isinstance(value,int):
                attrs[key.upper()]=value
                attrs.pop(key)
        print ‘In[%s:From-->%s]==>testMetaclass‘%(name,bases)
        return super(testMetaclass,cls).__new__(cls,name,bases,attrs)
    def __call__(cls,*args):
        print ‘call metaclass‘
        return super(testMetaclass,cls).__call__(*args)

自定义类testMetaclass(一般定义元类的命名可以在类名末尾加上Metaclass :P)作为__metaclass__元类属性,在元类创建类的时候,调用__new__方法,要在创建前“做些事”也是在这个方法中实现。__call__方法是创建的类实例化的时候才会被调用。这个也可以在实例化前“做些事”..:)

值得注意的是:

#若把__metaclass__属性放置于module level,也是任何作用都没有。。囧。但是把其只放置于父类Myclass中,子类也会被影响;把其只放置于子类中,父类不会被影响。
class MyClass(object):
    __metaclass__ = testMetaclass
    lower = 123
    strs = ‘string in MyClass..‘
class MySubClass(MyClass):
    kid_lower = 456
    kid_strs = ‘string in MySubClass..‘

【输出:】

放于父类的结果:

1 In[MyClass:From-->(<type ‘object‘>,)]==>testMetaclass
2 In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]==>testMetaclass

放于子类的结果:

In[MySubClass:From-->(<class ‘__main__.MyClass‘>,)]==>testMetaclass

  

(二)我用metaclass干嘛啊?

一般情况下,如果要对方法或者属性进行使用前的“额外操作”,可以使用decorator 或者 descriptor ,对于动态的创建类也是有很多方法可以实现,不过,metaclass可以让我们在想要对类创建前进行各种操作需求的时候方便的提供工作。

  • 拦截类的创建,对传入的要创建的类的各项参数进行操作;<如果在module level可以进行类的拦截,那....>
  • 筛选要创建的类,进行针对性的操作。
  • 检查接口API
  • 等等等

(三)一些相关链接

stackoverflow文章:What is a metaclass in Python?     ||  中文翻译

浅析 Python 的 metaclass

廖雪峰官方教程:(使用元类)

时间: 2024-10-10 11:59:34

metaclass(元类)的小探索的相关文章

metaclass元类解析

一.创建类的流程 二.什么是元类 在Python3中继承type的就是元类 示例 # 方式一 class MyType(type): '''继承type的就是元类''' def __init__(self,*args,**kwargs): print("MyType创建的对象",self) #Foo super(MyType,self).__init__(*args,**kwargs) def __call__(self, *args, **kwargs): obj = super(M

python中的元类metaclass

元类MetaClass 元类是可以让你定义某些类是如何被创建的.从根本上说,赋予你如何创建类的控制权. 元类也是一个类,是一个type类. 元类一般用于创建类.在执行类定义时,解释器必须要知道这个类的正确的元类,如果此属性没有定义,它会向上查找父类中的__metaclass__属性.如果还没发现,就查找全局变量. 对于传统类来说,它们的元类是types.ClassType. 元类也有构造器,传递三个参数:类名,从基类继承数据的元组,和类属性字典 下面我们来定义一个元类,要求写类的时候必须给类提供

深刻理解Python中的元类(metaclass)以及元类实现单例模式

深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对python的面向对象有了更加深入的了解.这里将一篇写的非常好的文章基本照搬过来吧,这是一篇在Stack overflow上很热的帖子,我看http://blog.jobbole.com/21351/这篇博客对其进行了翻译. 一.理解

Python第二十一课(反射/元类)

Python第二十一课(反射/元类)    >>>思维导图>>>中二青年 反射reflect 什么是反射, 其实是反省,自省的意思 反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力 反射就是通过字符串操作属性 涉及的四个函数,这四个函数就是普通的内置函数 没有双下划綫,与print等等没有区别 hasattr getattr setattr delattr p = Person("jack",18,"man") #

84、flask之信号和mateclass元类

本篇导航: flask实例化参数 信号 metaclass元类解析 一.flask实例化参数 instance_path和instance_relative_config是配合来用的:这两个参数是用来找配置文件的,当用app.config.from_pyfile('settings.py')这种方式导入配置文件的时候会用到 from flask import Flask,request app = Flask(__name__,instance_path=None, instance_relat

深刻理解Python中的元类(metaclass)

译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了985点的赞同点数,更有人评论说这段回复应该加入到Python的官方文档中去.而e-satis同学本人在Stack Overflow中的声望积分也高达6

深刻理解Python中的元类metaclass(转)

本文由 伯乐在线 - bigship 翻译 英文出处:stackoverflow 译文:http://blog.jobbole.com/21351/ 译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了9

python——深刻理解Python中的元类(metaclass)

译注:这是一篇在Stack overflow上 很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子 和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了985点的赞同点数,更有人评论说这段 回复应该加入到Python的官方文档中去.而e-satis同学本人在Stack Overflow中的声望积分也

[转] 深刻理解Python中的元类(metaclass)

非常详细的一篇深入讲解Python中metaclass的文章,感谢伯乐在线-bigship翻译及作者,转载收藏. 本文由 伯乐在线 - bigship 翻译.未经许可,禁止转载!英文出处:stackoverflow.欢迎加入翻译组. 译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及