Type, Object & Metaclass in Python
type和object的关系
一句话简述:types是objects的一个子类,objects是type的一个实例。在Python的世界中,object是类父子关系的顶端,所有的数据类型的父类都是它;type是类型实例关系的顶端,所有对象都是它的实例。它们两个的关系可以这样描述:

- 白板上的第一列,目前只有
type,我们先把这列的东西叫Type。 - 白板上的第二列,它们既是第三列的类型,又是第一列的实例,我们把这列的对象叫
TypeObject。 - 白板上的第三列,它们是第二列类型的实例,而没有父类(__bases__)的,我们把它们叫
Instance。
metaclass
metaclass常被用来在类实例化前做一些动态更改类属性的事情,比如,依赖于自省,控制继承等等。它的作用简而言之为:
- 中断类的默认创建
- 修改类属性,方法等
- 返回修改后的类
metaclass继承自type,是类的类。
以下是一个最简单的metaclass例子
class MyMetaclass(type):
def __new__(cls, name: str, bases: set, attrs: dict) -> type:
# some custom process
attrs_processed = {}
for name, val in attrs.items():
if not name.startswith('__'):
uppercase_attr[name.upper()] = val
else:
uppercase_attr[name] = val
return super().__new__(cls, name, bases, attrs_processed)
metaclass的一个主要用途就是构建API。Django(一个python写的web框架)的ORM就是一个例子。
用Django先定义了以下Model:
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
然后执行下面代码:
guy = Person.objects.get(name='bob')
print guy.age # result is 35
这里打印的输出并不是IntegerField,而是一个int,int是从数据库中获取的。
这是因为models.Model使用metaclass来实现了复杂的数据库查询。但对于你看来,这就是简单的API而已,不用关心背后的复杂工作。