[Advanced Python] 15 - "Metaclass": ORM

From: 使用元类app

动态建立类

与静态语言最大的不一样,就是函数和类的定义,不是编译时定义的,而是运行时动态建立的。函数

一 、type()动态建立

咱们说class的定义是运行时动态建立的;测试

建立class的方法就是使用type()函数。spa

type()函数既能够返回一个对象的类型,又能够建立出新的类型。code

 

问题来了:type建立了一个类?如何理解。如下即是一个 “动态建立” 的过程。对象

>>> def fn(self, name='world'): # 先定义函数
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 建立Hello class
>>> h = Hello() >>> h.hello() Hello, world. >>> print(type(Hello)) <class 'type'> >>> print(type(h)) <class '__main__.Hello'>

 

 

2、metaclass

要控制类的建立行为,还能够使用metaclass。blog

metaclass,直译为元类,简单的解释就是:先定义metaclass,就能够建立类,最后建立实例。get

因此,metaclass容许你建立类或者修改类。换句话说,你能够把“类”当作是metaclass建立出来的“实例”编译

metaclass是Python面向对象里最难理解,也是最难使用的魔术代码。模板

 

神奇之处

正常状况下,你不会碰到须要使用metaclass的状况。

[实验]:经过metaclass给咱们自定义的MyList增长一个add方法。

定义ListMetaclass,按照默认习惯,metaclass的类名老是以Metaclass结尾,以便清楚地表示这是一个metaclass:

# metaclass是类的模板,因此必须从`type`类型派生:
classListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)  # 添加了add方法 return type.__new__(cls, name, bases, attrs)

 

 

有了ListMetaclass,咱们在定义类的时候还要指示使用ListMetaclass来定制类,传入关键字参数metaclass

class MyList(list, metaclass=ListMetaclass):
    pass

 

测试了一下,MyList能够调用add方法。

>>> L = MyList()
>>> L.add(1)
>> L
[1]

 

 

动态修改有什么意义?

直接在MyList定义中写上add()方法不是更简单吗?正常状况下,确实应该直接写,经过metaclass修改纯属变态。

可是,总会遇到须要经过metaclass修改类定义的。ORM就是一个典型的例子。

 

/* implement */

 

 

 

 

End.

相关文章
相关标签/搜索