首页 > 编程 > Python > 正文

python元类

2019-11-08 18:35:34
字体:
来源:转载
供稿:网友

注:这是我整理的一些学习笔记,大部分是别人的文章,也加了一些个人理解。使用的是python3.5

参考这些博客:http://blog.jobbole.com/21351/http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python__new__和__init__参考这里:点击打开链接使用type()生成类:type(类名,父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))Foo = type('Foo', (), {'bar': True})# 也可以MyClass = type('Foo', (), {'bar': True})'''等价于:class Foo(object):   bar = True'''PRint(Foo)test = Foo()print(test)'''<class '__main__.Foo'><__main__.Foo object at 0x01FCD310>'''# 可以继承:Deri = type('Deri', (Foo,), {})print(Deri)'''<class '__main__.Deri'>'''# 添加方法:def func():    print('I add a method now...')Deriv = type('Deriv', (Foo,), {'func': func})print(hasattr(Foo, 'func'))print(hasattr(Deriv, 'func'))'''FalseTrue'''print(Deri.__class__)'''<class 'type'>'''class Foo(object):    passprint(Foo.__class__)print(Foo.__class__.__class__)'''<class 'type'><class 'type'>'''class Foo(object):    passFoo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧跟我的思路)。如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。
# 请记住,'type'实际上是一个类,就像'str'和'int'一样# 所以,你可以从type继承class UpperAttrMetaClass(type):    # __new__ 是在__init__之前被调用的特殊方法    # __new__是用来创建对象并返回之的方法    # 而__init__只是用来将传入的参数初始化给对象    # 你很少用到__new__,除非你希望能够控制对象的创建    # 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__    # 如果你希望的话,你也可以在__init__中做些事情    # 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用    def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr):        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))        uppercase_attr = dict((name.upper(), value) for name, value in attrs)        return type(future_class_name, future_class_parents, uppercase_attr)class UpperAttrMetaclass(type):    def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr):        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))        uppercase_attr = dict((name.upper(), value) for name, value in attrs)        # 复用type.__new__方法        # 这就是基本的OOP编程,没什么魔法        return type.__new__(upperattr_metaclass, future_class_name, future_class_parents, uppercase_attr)'''你可能已经注意到了有个额外的参数upperattr_metaclass,这并没有什么特别的。类方法的第一个参数总是表示当前的实例,就像在普通的类方法中的self参数一样。当然了,为了清晰起见,这里的名字我起的比较长。但是就像self一样,所有的参数都有它们的传统名称。因此,在真实的产品代码中一个元类应该是像这样的:'''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 type.__new__(cls, name, bases, uppercase_attr)'''为防止出现基类重复构造,使用__super__'''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, base, uppercase_attr)ss


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表