以下是不可取的,而且你會打很多的問題和cornercases實現你的想法,但關於Python 3.1及以後,你可以通過重寫掛接到定製類的創建過程中,__build_class__
內置掛鉤:
import builtins
_orig_build_class = builtins.__build_class__
class SomeMockingMeta(type):
# whatever
def my_build_class(func, name, *bases, **kwargs):
if not any(isinstance(b, type) for b in bases):
# a 'regular' class, not a metaclass
if 'metaclass' in kwargs:
if not isinstance(kwargs['metaclass'], type):
# the metaclass is a callable, but not a class
orig_meta = kwargs.pop('metaclass')
class HookedMeta(SomeMockingMeta):
def __new__(meta, name, bases, attrs):
return orig_meta(name, bases, attrs)
kwargs['metaclass'] = HookedMeta
else:
# There already is a metaclass, insert ours and hope for the best
class SubclassedMeta(SomeMockingMeta, kwargs['metaclass']):
pass
kwargs['metaclass'] = SubclassedMeta
else:
kwargs['metaclass'] = SomeMockingMeta
return _orig_build_class(func, name, *bases, **kwargs)
builtins.__build_class__ = my_build_class
這僅限於自定義類只有,但確實給你一個全能的鉤。
對於3.1之前的Python版本,您可以忘記掛鉤創建類。如果沒有定義元類,則C build_class
function直接使用C型type()
值,但它從不從__builtin__
模塊查找它,因此無法覆蓋它。
這甚至是可取的嗎?你說「每個對象」。你知道整數和字符串是對象嗎? Python中的每個值都是一個對象。不清楚的是,你可以自動分離有趣的對象進行審查。爲什麼每個物體都要加倍呢?你怎麼知道被測系統是什麼? – 2013-03-08 11:51:27
@NedBatchelder我知道這個問題會來。當你正在進行單元測試時,你需要確保你只測試一個**單元**。必須嘲笑該單位的相關性才能做到這一點。當然,整數和字符串不會被嘲笑,但是每個與它們有關的方法(例如str.split)都會被嘲笑。簡而言之,在可能的情況下會有例外和合理的雙打。開發者將指定被測試的系統是什麼。 – 2013-03-08 12:11:06
我認爲嘲笑str.split是矯枉過正的。嘲笑某事的原因是因爲你想將自己與它隔離開來,因爲你不相信它,或者它是不可預測的,或者它太慢了。 Str.split不屬於任何這些類別。 – 2013-03-08 13:05:44