Duck Typing,isinstance(),_ _ subclasshook __()重写,和types.MethodType()一起工作?

时间:2015-08-20 17:33:01

标签: python

我正在开发一个项目,我有一个类,它根据初始化的条件实现一组动态绑定方法。这样做的目的是通过创建包含一系列绑定到对象的方法的新模块,使库的功能很容易扩展,同时还将库的API简化为不积极参与的库。

它不是一个完美的并行,但为了表示这一点,我将使用一个def speak(self): print 'Woof!' def speak_name(self): # This is a very talented dog print self.name def quack(self): print 'Quack!' 类,在初始化时,从一个技巧模块中获取一系列技巧,在这种情况下,它将作为包含模块名称。

ABCMeta

然后,由于这些将被指定为绑定方法,因此技巧模块可以包含访问类'属性如:

__subclasshook__

现在我终于到了我努力奋斗的部分。使用instance()DuckABC方法可以更改is quack()方法的行为,以便它为实现特定方法的任何类返回true。例如,我们可以有一个class DuckABC: __metaclass__=ABCMeta @abstractmethod def quack(self): pass @classmethod def __subclasshook__(cls, instance): if cls is DuckABC: if any("quack" in class_.__dict__ for class_ in instance.__mro__): return True return NotImplemented class Cat(object): def __init__(self, name): self.name=name def quack(self): # Not a very talented cat print 'meow' >>> my_cat = Cat('Tom') >>> isinstance(my_cat, DuckABC) True 抽象基类,本质上用作一个接口,对于任何实现DuckABC方法的类,它都返回true。

Dog

然而,这是我的问题出现的地方。使用此>>> my_dog = Dog('Berkley', 'name_of_module_containing_quack') >>> my_dog.quack() Quack! >>> isinstance(my_dog, DuckABC) False 抽象基类和上面定义的动态Dog类,将会出现以下情况:

quack

我理解它没有返回true,因为Dog类本身没有任何名为isinstance()的方法,尽管{{1}}类的这个特定实例学会了如何嘎嘎。

所以我的问题是:在这个框架中有没有办法使用{{1}}方法来检查我的狗类的特定实例是否知道如何嘎嘎?如果没有,我可能有什么其他选择来实现相同的功能?

2 个答案:

答案 0 :(得分:2)

我会更简单:

class QuackMixin(object):
    def quack(self):
        ...

class Dog(object):
    ...

class QuackingDog(Dog, QuackMixin):
    pass

quacking_dog = QuackingDog(...)

isinstance(quacking_dog, Dog) -> True
isinstance(quacking_dog, QuackMixin) -> True
isinstance(quacking_dog, QuackingDog) -> True

因此,您的tricks模块将包含mixins。您可以创建一个工厂函数来生成所需类的子类/实例:

def make_special_dog_class(class_name, *classes):
    return type(class_name, tuple(classes), {})

答案 1 :(得分:1)

使用hasattr

if hasattr(dog, "Quack"): 
    dog.Quack()
else: 
    dog.Sit()