[TimLinux] Python 再谈元类 metaclass

本博文通过对以下链接进行理解后,编写。

https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python

1. 类

类也是对象,具有对象的特点:

  • 你可以将它赋值给变量
  • 你可以copy它
  • 你可以给它添加属性
  • 你可以把它作为函数参数进行传递

类定义语法:

class Foo(object): pass

说明:
1. 这是一种语法糖,一种对类对象的声明方式,与def func, a = 123, 本质上没有区别,都是为了创建一个对象。
2. 对象的创建都关联到一个类,比如 a = 123 关联的类是 'int', b = 'hello' 关联的类是 'str', 
def func(): pass 关联的类是 'function', 而 class Foo(object): pass 关联的类就是元类 'metaclass', 默认为 'type'

对象重要特性:动态创建,你可以随时随地在你需要的地方创建对象,类也可以动态创建。

2. 动态创建

根据函数参数来创建类,看起来像是类工厂,但是动态性不够。

def choose_class(name):
    if name == 'foo':
        class Foo(object): pass
        return Foo # return the class, not an instance
    else:
        class Bar(object): pass
        return Bar

>>> MyClass = choose_class('foo')
>>> print(MyClass) # the function returns a class, not an instance
<class '__main__.Foo'>
>>> print(MyClass()) # you can create an object from this class
<__main__.Foo object at 0x89c6d4c>

真正的动态创建,是通过元类(默认type类构造函数)来创建:

# 创建类
>>> Foo = type('Foo', (), {'bar':True})
>>> print(Foo)
<class '__main__.Foo'>
>>> print(Foo.bar)
True
>>> f = Foo()
>>> print(f)
<__main__.Foo object at 0x8a9b84c>
>>> print(f.bar)
True

# 创建子类
>>> FooChild = type('FooChild', (Foo,), {})
>>> print(FooChild)
<class '__main__.FooChild'>
>>> print(FooChild.bar) # bar is inherited from Foo
True

# 给子类分配实例方法
>>> def echo_bar(self):
...       print(self.bar)
...
>>> FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
>>> hasattr(Foo, 'echo_bar')
False
>>> hasattr(FooChild, 'echo_bar')
True
>>> my_foo = FooChild()
>>> my_foo.echo_bar()
True

# 再分配一个实例方法
>>> def echo_bar_more(self):
...       print('yet another method')
...
>>> FooChild.echo_bar_more = echo_bar_more
>>> hasattr(FooChild, 'echo_bar_more')
True

猜你喜欢

转载自www.cnblogs.com/timlinux/p/9698729.html