如果我这样做:
from mailbox import Mailbox
Mailbox.get = 'dummy'
没有错误,我只是替换了get
方法。但如果我做一个:
from datetime import datetime
datetime.now = 'dummy'
我得到:
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
这很奇怪,因为源代码在/usr/lib/python3.6/datetime.py
上是可读的。我想这个库是出于性能原因编译的,这就是为什么它不能被修改的原因。但是,问题是:我怎么知道一个类是不可变的,因为它是内置的或扩展的(而不是像我那样只进行测试(?为什么我可以修补Mailbox
类而不能修补datetime
类?
它不会直接告诉您,但对于您的案例,您可以测试您试图替换的方法,看看它是否是types.BuiltinMethodType
:的实例
>>> isinstance(Mailbox.get, types.BuiltinMethodType)
False
>>> isinstance(datetime.now, types.BuiltinMethodType)
True
inspect.isbuiltin
提供相同的信息:
>>> inspect.isbuiltin(Mailbox.get)
False
>>> inspect.isbuiltin(datetime.now)
True
需要明确的是,这是CPython引用解释器的一个限制;没有什么要求内置类型的属性/方法是不可变的,而在其他解释器(例如PyPy(中,它们可能是可变的。
简单,导入感兴趣的模块,并引用它:
>>> import math
>>> math
<module 'math' (built-in)>
>>> import numpy
>>> numpy
<module 'numpy' from 'C:\Users\User\AppData\Local\Programs\Python\Python38-32\lib\site-packages\numpy\__init__.py'>
正如您所看到的,math
是内置的,而numpy
不是。