通过定义类的元类的__instancecheck__()
特殊方法,可以控制对象何时作为该类的成员进行测试。如果你有一个预定义的类P(比如一个内置类)并且你想有条件地控制你的类C的给定实例是否作为P类型的对象测试怎么办?可以这样做吗?
这是一个愚蠢的例子:
class C:
def __init__ (self, x, y):
self.x = x
self.y = y
假设我希望C作为类numbers.Number
的对象进行测试,但仅限于x > y
和y % 3 == 0
。 (我说这将是一个愚蠢的例子。)
from numbers import Number
assert isinstance(C(4, 3), Number)
assert not isinstance(C(1, 3), Number)
assert not isinstance(C(4, 2), Number)
可以这样做吗?怎么样?
答案 0 :(得分:1)
方法__instancecheck__()
是在要测试的类上定义的 - 在本例中是类numbers.Number
。该类使用abc.ABCMeta
作为其元类(请参阅source code)。机制ABCMeta
提供了更多应该被视为类实例的类register()
method。为了完全满足您的要求,您必须使用numbers.Number
的某个自定义子类替换ABCMeta
的元类,该子类将覆盖__instancecheck__()
以提供所需的功能。通过为numbers.Number.__class__
分配一个新类,可以在CPython中实现这一点,但这并不能保证在其他python实现中有效。
import abc
import numbers
class C(object):
def __init__(self, x, y):
self.x = x
self.y = y
def is_number(self):
return self.x > self.y and not self.y % 3
class NumberMeta(abc.ABCMeta):
def __instancecheck__(self, obj):
if type(obj) is C:
return obj.is_number()
return abc.ABCMeta.__instancecheck__(obj)
numbers.Number.__class__ = NumberMeta
assert isinstance(C(4, 3), Number)
assert not isinstance(C(1, 3), Number)
assert not isinstance(C(4, 2), Number)
那就是说,实际做这样的事情似乎是一个糟糕的主意。为什么你认为你需要这个?