Python技巧:元类(Metaclasses)和利用Type构建的动态类(Dynam
`metaclass`和`type`关键字在Python代码中较少被使用(也正因如此,它们的作用也没有很好的被理解)。在这篇文章中,我们将探究`type()`的类型(types)和跟`metaclasses`相关的`type`的用法。 这是我的类型么? 首先来看`type()`的第一个广为人知的用法,即查看一个对象的类型。Python初学者常常会对此有这样的疑问:“我认为Python中是没有类型的啊!”可事实正相反,Python中的一切都有类型(即使是类型关键字‘types’本身!),这是因为Python中的一切都是对象(object)。下面来看几个例子: >>>?type(1) <class?'int'> >>>?type('foo') <class?'str'> >>>?type(3.0) <class?'float'> >>>?type(float) <class?'type'> `type`的类型 一切看起来都是那么理所当然,直到我们查看float的类型,`<class 'type'>`?这是怎么回事?继续往下看: >>>?class?Foo(object): ...?????pass ... >>>?type(Foo) <class?'type'> 啊,我们又看到了`<class 'type'>`。很显然,所有类自身的类型都是`type`(无论是内建类型或是用户定义类型的类)。那么`type`的`type`又是什么呢? >>>?type(Foo) <class?'type'> 好吧,测试到此为止。`type`是所有类型的类型,包括它自身。事实上,`type`是一个元类`metaclass`,也就是“一个用来构建类的东西”。诸如`list()`这样的类,是用来构建类的实例(instances),例如`my_list=list()`。而元类则以同样的方式来构建类型,例如以下代码: class?Foo(object): ????pass 创建自己的元类 与常规类类似,元类也可以由用户自定义。具体用法是将目标类的`__metaclass__`属性设置为自定义的`metaclass`。`metaclass`必须是可调用(callable)的,并且返回一个`type`。通常,用户可以使用一个函数来设置`__metaclass__`属性,这个函数是`type`的另一种用法:利用三个参数创建一个新类。 `type`的另一面 如上文所述,`type`有着另一种完全不同的用法。这种用法由传入三个参数:type(name,bases,dict)能够创建一个新的类型。以下是创建一个新类的通常做法: class?Foo(object): ????pass 而我们能够通过以下的代码达到同样的效果: Foo?=?type('Foo',?(),?{}) 目前Foo是一个名为“Foo”的类的引用,这个名为“Foo”的类以object为基类(通过type创建的类,如果没有特别指定其基类,将会默认创建新类型的类)。 这么做看起来非常棒,但如果我们需要向Foo中添加成员函数该怎么办呢?这很容易通过设置Foo的类属性办到: def?always_false(self): ????return?False Foo.always_false?=?always_false 上面的代码也能够写成如下形式:
|