3 道练习题·预计 30 分钟·做对一题解锁下一段
先送一句 Tim Peters(Python 界的资深玩家)说过的话:
元类是深度的魔法,99% 的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。
听起来好像在劝退。但既然元类是 Python 类型系统的根,了解一下它可以让你真正看懂 class 关键字背后发生了什么。
在大多数语言里,类是「描述如何生成对象的代码段」。Python 也是这样——但 Python 多了一层:
在 Python 中,类本身也是一个对象。
这听起来有点绕。下面这段最普通的代码:
class ObjectCreator:
pass
obj = ObjectCreator()
print(obj)
print(ObjectCreator)输出(地址会不同):
<__main__.ObjectCreator object at 0x...>
<class '__main__.ObjectCreator'>
注意第二行——ObjectCreator 这个类,本身也能被打印。也就是说它是个对象。既然是对象,我们就能:
class ObjectCreator:
pass
# 把类当参数传给函数
def echo(x):
print(x)
echo(ObjectCreator)
# 把类赋值给变量
Alias = ObjectCreator
print(Alias)输出:
<class '__main__.ObjectCreator'>
<class '__main__.ObjectCreator'>
类可以传参、可以赋值、可以打印——和函数一样,是「一等公民」。
type() 不止是「查类型」各位都用过 type() 函数——查一个变量是什么类型:
print(type(123))
print(type('abc'))输出:
<class 'int'>
<class 'str'>
这是 type() 的第一种用法:传一个对象,返回它的类型。
那如果我把一个类传给 type() 呢?
class Hello:
def hi(self):
print('Hello')
h = Hello()
print(type(h)) # 实例的类型
print(type(Hello)) # 类的类型输出:
<class '__main__.Hello'>
<class 'type'>
注意第二行——Hello 这个类的类型是 type。
换句话说:Hello 是 type 的一个实例。
Python 里所有东西都是对象,都有 __class__ 属性:
print((123).__class__)
print('abc'.__class__)
def fn(): pass
print(fn.__class__)
class Eat: pass
print(Eat().__class__)输出:
<class 'int'>
<class 'str'>
<class 'function'>
<class '__main__.Eat'>
这些 class 自己又是从哪儿来的?继续往上一层:
print((123).__class__.__class__)
print('abc'.__class__.__class__)
print(Eat().__class__.__class__)输出:
<class 'type'>
<class 'type'>
<class 'type'>
全是 type。这就是核心结论:
type是 Python 内建的「元类」——所有类的类。
| 对象 | 它的类 |
|---|---|
123 | int |
'abc' | str |
int / str / 你自己写的类 | type |
「类」也是「对象」——是 type 的实例。这就是元类的第一层意思。
请定义一个最普通的类 Foo(里面写 pass 即可)。
然后用 type() 检查 Foo 的类型,再用 is 判断它是不是 type,按下面的格式打印两行:
<class 'type'>
True
提示:第一行是 print(type(Foo)),第二行是 print(type(Foo) is type)。