这是一个尝试创建一个装饰器的玩具示例,该装饰器允许声明属性名称,这应该是标准__subclasshook__和__instancecheck__模式中“接口检查”的必需部分。
Foo当我装饰班级时,它似乎按预期工作。我创建了一个Bar与 无关的类Foo,但它具有所需的属性,并且正确满足isinstance(instance_of_bar, Foo) == True.
但是作为另一个例子,我创建了一个dictaugmented 的子类,这样这些key值也可以通过getattr语法访问(例如,可以用dictwhered['a']替换d.a以获得相同的结果)。在这种情况下,属性只是实例属性,所以__instancecheck__应该可以工作。
这是代码。请注意,鉴于带有实例的示例,将函数Bar“monkeypatch”到类(具有元类)中的选择可以正常工作。所以似乎不必直接在元类的类定义中定义函数。__subclasshook__Foo
#Using Python 2.7.3
import abc
def interface(*attributes):
def decorator(Base):
def checker(Other):
return all(hasattr(Other, a) for a in attributes)
def __subclasshook__(cls, Other):
if checker(Other):
return True
return NotImplemented
def __instancecheck__(cls, Other):
return checker(Other)
Base.__subclasshook__ = classmethod(__subclasshook__)
Base.__instancecheck__ = classmethod(__instancecheck__)
return Base
return decorator
@interface("x", "y")
class Foo(object):
__metaclass__ = abc.ABCMeta
def x(self): return 5
def y(self): return 10
class Bar(object):
def x(self): return "blah"
def y(self): return "blah"
class Baz(object):
def __init__(self):
self.x = "blah"
self.y = "blah"
class attrdict(dict):
def __getattr__(self, attr):
return self[attr]
f = Foo()
b = Bar()
z = Baz()
t = attrdict({"x":27.5, "y":37.5})
print isinstance(f, Foo)
print isinstance(b, Foo)
print isinstance(z, Foo)
print isinstance(t, Foo)
印刷:
True
True
False
False
这只是一个玩具示例——我不是在寻找更好的方法来实现我的attrdict课程。该Bar示例演示了猴子补丁的__subclasshook__工作方式。其他两个示例演示了__instancecheck__仅具有要检查的实例属性的实例的失败。在那些情况下,__instancecheck__甚至没有调用。
我可以手动检查(即,根据需要)或__instancecheck__的实例是否满足我的函数的条件。attrdicthasattr(instance_of_attrdict, "x")Truez
同样,对于Bar. 这表明__subclasshook__装饰器正在正确应用,并且修补自定义__metaclass__不是问题。但是__instancecheck__在这个过程中似乎没有被调用。
为什么可以__subclasshook__在元类的类定义之外定义并在以后添加,但不能__instancecheck__?