python2.7 模块全局__metaclass__

metaclass概述

metaclass 像一个魔法盒,可以动态修改python 类对象 的属性及方法等。没错,我这里暂且称之为类对象,
因为它以对象的方式来表示一个类(比如 class Myclass:pass);在python中,一切皆对象。

本文主要介绍在python2.7的环境下,如何增加模块级的__metaclass__。

对于不清楚metaclass的同学,可以参考这篇文章:
深刻理解 Python 中的元类(metaclass)

采用函数方法增加模块metaclass

代码如下:

# metaclass函数
def upper(cls_name, cls_parents, cls_attr):
    """ Make all class attributes uppper case """
    attrs = ((name, value) for name, value in cls_attr.items()
            if not name.startswith('__'))
    upper_atts = dict((name.upper(), value) for name, value in attrs)
    return type(cls_name, cls_parents, upper_atts)

 __metaclass__ = upper #module level

class Foo:
    foo = 1

class Bar:
    bar = 1

此时,Foo类中的的foo属性变成了Foo,Bar类中的的bar属性变成了BAR。如果只需要对某个类增加metaclass属性,则只需要在该类中增加 metaclass = upper。

注意:在python3.5中,不支持这种方式来定论模块metaclass属性。

采用OPP方式增加模块metaclass

一开始开心地以为可以直接采用类似函数的方式来实现模块级metaclass,代码如下:

class UpperAttrMetaclass(type):
    def __new__(cls, name, bases, dct):
        attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)
        return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

__metaclass__ = UpperAttrMetaclass

class Foo(object):
    foo = 1

    def __init__(self, foo1):
        self.foo1 = foo1

此时还高兴的以为Foo增加了metaclass属性,将foo属性变成了FOO; 而实际上并没有。多么痛的领悟啊!那怎么办呢?经过各种查,找到了一个解决方法,可以采用继承的方式来实现metaclass属性,而且这各方式还可以灵活的选择所要继承的metaclass
代码如下:

class UpperAttrMetaclass(type):
    def __new__(cls, name, bases, dct):
        attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)
        return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

class Up(object):
    __metaclass__ = UpperAttrMetaclass

class Foo(Up):
    foo = 1

    def __init__(self, foo1):
        self.foo1 = foo1

该方法可以解决python3.5中不支持 函数式metaclass 的问题

也许还有更好的方法,望大神们指正与探讨!!!

猜你喜欢

转载自blog.csdn.net/LClansefengbao/article/details/51383207
今日推荐