gpt4 book ai didi

python - Duck Typing、isinstance()、__subclasshook__() 覆盖和 types.MethodType() 一起工作?

转载 作者:行者123 更新时间:2023-11-28 16:30:48 25 4
gpt4 key购买 nike

我正在开发一个项目,其中有一个类根据初始化条件实现一组动态绑定(bind)方法。这样做的目的是通过创建一个包含一系列方法的新模块,使库的功能易于扩展,这些方法将绑定(bind)到对象,同时也为那些没有积极贡献的人简化了库的 API .

这不是一个完美的平行,但为了表示这一点,我将使用一个 Dog 类,它在初始化时从一个技巧模块中获取一系列技巧,在这种情况下,这些技巧将作为一个包含模块名称的字符串。

class Dog(object):
def __init__(self, name, module_name):
self.name = name
# imports module
module = __import__("mylib.tricks.{mod}".format(mod=module_name),
from_list=['arbitrary argument'])
# Dog object gets all tricks from module as bound methods
tricks = module.__all__
for trick in tricks:
exec("self." + trick + "=types.MethodType(" + trick + ", self)")

然后,由于这些将被分配为绑定(bind)方法,因此 tricks 模块可以包含访问类属性的方法,例如:

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__ 方法可以更改 is instance() 方法的行为,以便它为任何类返回 true实现特定方法。例如,我们可以有一个 DuckABC 抽象基类,本质上用作一个接口(interface),它也为任何实现 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 抽象基类和上面定义的动态 Dog 类,以下内容为真:

>>> my_dog = Dog('Berkley', 'name_of_module_containing_quack')
>>> my_dog.quack()
Quack!
>>> isinstance(my_dog, DuckABC)
False

我知道它没有返回 true,因为 Dog 类本身没有任何名为 quack 的方法,尽管 的这个特定实例Dog 类(class)学会了嘎嘎叫。

所以我的问题是:在此框架内是否有任何方法可以使用 isinstance() 方法来检查我的狗类的特定实例是否知道如何嘎嘎叫?如果没有,我可能还需要哪些其他选项才能实现相同的功能?

最佳答案

我会变得更简单:

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 模块将包含混入。您可以制作一个工厂函数,该函数制作所需类的子类/实例:

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

关于python - Duck Typing、isinstance()、__subclasshook__() 覆盖和 types.MethodType() 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32124683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com