理解python元类

本文翻译自stackoverflow的回答,链接: 点击打开链接
修改了一些代码例子,写到这里来是做个记录这里,也让自己更好的记住元类的概念。
一、掌握class
类也是对象,动态的创建类,创建了类之后,还可以给类添加方法和属性,就像给普通类添加方法和属性一样
可以对类进行的操作:
  • 把类对象赋值个一个变量
  • 复制类
  • 给类增加属性
  • 把类对象当作参数传递给一个函数
class ObjectCreator():
	pass
ObjectCreator.new_attr = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))

输出:False

设置新的属性:

ObjectCreator.new_attribute = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))

输出:True

把类对象赋值给一个变量:

ObjectCreatorMirror = ObjectCreator
print(ObjectCreatorMirror.new_attribute)

输出:foo

2.动态创建类:

type(name of the class,
     tuple of the parent class (for inheritance, can be empty),
     dictionary containing attributes names and values)

例子:

MyShinyClass = type('MyShinyClass', (), {})

以上代码等同于:

class MyShinyClass(object):
...       pass

二、元类

元类,用来创建类,定义类来创建对象,定义元类创建类。

type是一个类,是元类,是一个“类工厂”,主要作用是创建API。

Combined with the normal __init__ and __new__ methods, metaclasses therefore allow you to do 'extra things' when creating a class, like registering the new class with some registry, or even replace the class with something else entirely.

def upper_attr(future_class_name,future_class_parents,future_class_attr):
    uppercase_attr = {}
    for name,val in future_class_attr.items():
        if not name.startswith('__'):
            uppercase_attr[name.upper()] = val
        else:
            uppercase_attr[name] = val
    return type(future_class_name,future_class_parents,future_class_attr)

class Foo():

    bar = 'bip'

print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))

输出:False,True

使用元类来实现:

#使用元类
class UpperAttrMetaClass(type):
    def __new__(mcs, future_class_name,future_class_parents,future_class_attr):
        uppercase_attr = {}
        for name,val in future_class_attr.items():
            if not name.startswith('__'):
                uppercase_attr[name.upper()] = val
                print(name.upper())
            else:
                uppercase_attr[name] = val
        #调用父类的__new__方法创建对象,也可以直接type()
        # return type(future_class_name, future_class_parents, uppercase_attr)
        return type.__new__(mcs,future_class_name,future_class_parents,uppercase_attr)

class Foo(metaclass=UpperAttrMetaClass):
    bar = 'bip'
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))

输出:False,True

自定义元类练习:

#自定义元类练习
class PersonMeta(type):
    # def __new__(mcs,name,bases,dict):
    #     dict['age'] = 25
    #     return type.__new__(mcs,name,bases,dict)
    def __new__(cls, *args, **kwargs):
        print('new')
        name,bases,attr = args[:3]
        attr['age'] = 23
        attr['temper'] = 'bad'
        return type.__new__(cls,name,bases,attr)

    def __init__(self,name,bases,attr):
        self.temper = 'good'
        print('init',attr)


class XiaoMing(metaclass=PersonMeta):
    gender = 'Male'

x = XiaoMing()
print(x.age)
print(x.temper)


猜你喜欢

转载自blog.csdn.net/smh2208/article/details/80869215