初探元编程

type

type 是python 内置元类,为改变 Python 中类的行为(比如,SomeClass 的行为),我们可以通过继承 type 元类,定义一个自定义元类。元类是在 Python 中进行元编程的一种方法

1
2
3
4
class SomeClass:
pass
some_object = SomeClass()
type(some_object) # __main__.SomeClass

1
2
3
4
5
6
7
>>> import inspect
>>>inspect.isclass(SomeClass)
True
>>>inspect.isclass(some_object)
False
>>>inspect.isclass(type(some_object))
True
1
2
3
4
5
6
7
8
>>> type(type(SomeClass))
<type 'type'>
>>>inspect.isclass(type(type(SomeClass)))
True
>>>type(type(type(SomeClass)))
<type 'type'>
>>>isclass(type(type(type(SomeClass))))
True

除 type 之外,Python 中的一切都是对象,它们要么是类的实例,要么是元类的实例。

1
2
3
4
5
6
7
>>> some_obj = SomeClass()
>>> isinstance(some_obj,SomeClass)
True
>>> isinstance(SomeClass, type)
True
>>> isinstance(some_obj,type)
False

在 Python 中使用 type 来创建类

通过一个参数调用 type 时,会生成现有类的 type 信息。通过三个参数调用 type 时,会创建一个新的类对象。调用 type 时,参数是类名、基类列表以及指定类的名称空间的字典(所有字段和方法)

1
SomeClass = type('SomeClass', (), {})

与下面等价

1
SomeClass = type('SomeClass', (), {})

此外

1
2
3
4
5
6
7
8
def some_function(self): 
print("Hello")

ParentClass = type('ParentClass', (), {})
SomeClass = type('SomeClass',
(ParentClass,),
{'some_function': some_function,
'some_var':5})

等价于

1
2
3
4
5
6
7
class ParentClass: 
pass

class SomeClass(ParentClass):
some_var = 5
def some_function(self):
print("Hello!")

元类

编写自定义元类分为两个步骤:

  1. 编写元类类型的子类。
  2. 使用元类挂钩将新元类插入到类创建流程中

    元类的实际使用

    因为在子类中会继承元类,所以元类解决了代码冗余(不要重复自己 — DRY)这一实际问题。 通常情况下,在生成类对象的同时,通过执行额外操作或添加额外代码,元类也可以帮助提取有关类创建的复杂逻辑。元类的一些实际用例包括:

  3. 抽象基类

  4. 类的注册
  5. 在库和框架中创建 API

抽象基类

抽象基类是只能被继承而不会被实例化的类

1
2
3
4
5
6
7
8
9
10
11
from abc import ABCMeta, abstractmethod

class Vehicle(metaclass=ABCMeta):

@abstractmethod
def refill_tank(self, litres):
pass

@abstractmethod
def move_ahead(self):
pass

创建一个从 Vehicle 类继承的 Truck 类:

1
2
3
4
5
6
7
8
9
10
11
class Truck(Vehicle): 
def __init__(self, company, color, wheels):
self.company = company
self.color = color
self.wheels = wheels

def refill_tank(self, litres):
pass

def move_ahead(self):
pass

调用

1
mini_truck = Truck("Tesla Roadster", "Black", 4)

(参考文档)[https://www.ibm.com/developerworks/cn/analytics/library/ba-metaprogramming-python/index.html]