python - 如何创建作为另一个类的子类但未通过issubclass和或isinstance测试的Python类?
2021/12/8 1:17:19
本文主要是介绍python - 如何创建作为另一个类的子类但未通过issubclass和或isinstance测试的Python类?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
我知道这可能是个糟糕的设计,但我遇到了一个需要动态创建类的子类Derived
的情况,并使Base
的实例无法通过Derived
或issubclass(Derived, Base)
检查(即返回isinstance(derived_obj, Base)
)。
我尝试过很多方法,但都没有成功:
在False
(class - How to fake type with Python - Stack Overflow)中创建名为__class__
的属性。这只能用于使支票返回Derived
。
重写True
的__instancecheck__
和__subclasscheck__
方法。这不起作用,因为CPython只在常规检查返回Base
时调用这些方法。
在False
期间指定__class__
属性。这在Python3.6+中不再允许。
制作__init__
子类并将其所有属性和方法(包括特殊方法)赋给Derived
子类。这不起作用,因为不能对不是object
子类的实例调用某些方法(例如Base
)。
这可能用Python完成吗?这种方法可以是特定于解释器的(代码只在CPython中运行),并且只需要针对Python 3.6+版本。
要说明此要求的潜在用途,请考虑以下功能:
def map_structure(fn, obj): if isinstance(obj, list): return [map_structure(fn, x) for x in obj] if isinstance(obj, dict): return {k: map_structure(fn, v) for k, v in obj.items()} # check whether `obj` is some other collection type ... # `obj` must be a singleton object, apply `fn` on it return fn(obj)
该方法将
__init__
推广到任意嵌套结构上。但是,在某些情况下,我们不希望遍历某个嵌套结构,例如:
# `struct` is user-provided structure, we create a list for each element struct_list = map_structure(lambda x: [x], struct) # somehow add stuff into the lists ... # now we want to know how many elements are in each list, so we want to # prevent `map_structure` from traversing the inner-most lists struct_len = map_structure(len, struct_list)
如果可以实现上述功能,则可以将上述更改为:
pseudo_list = create_fake_subclass(list) struct_list = map_structure(lambda x: pseudo_list([x]), struct) # ... and the rest of code should work
最佳答案
重写__instancecheck__
的__subclasscheck__
和Base
方法。这不起作用,因为CPython只在常规检查返回False
时调用这些方法。
这种说法是一种误解。这些钩子是在元类上定义的,而不是在基类上(docs)。
>>> class Meta(type): ... def __instancecheck__(self, instance): ... print("instancecheck", self, instance) ... return False ... def __subclasscheck__(self, subclass): ... print("subclasscheck", self, subclass) ... return False ... >>> class Base(metaclass=Meta): ... pass ... >>> class Derived(Base): ... pass ... >>> obj = Derived() >>> isinstance(obj, Base) instancecheck <class '__main__.Base'> <__main__.Derived object at 0xcafef00d> False >>> issubclass(Derived, Base) subclasscheck <class '__main__.Base'> <class '__main__.Derived'> False
请注意CPython性能优化,这些优化可防止在某些特殊情况下调用自定义实例检查挂钩(有关详细信息,请参见here)。尤其是,当存在精确匹配时,可能由于aCPython fast path而无法强arm返回值
isinstance(obj, Derived)
。最后一点,我同意评论人士的看法,那听起来不像是一个很有前途的设计。在这种情况下,似乎应该考虑使用组合而不是继承。
这篇关于python - 如何创建作为另一个类的子类但未通过issubclass和或isinstance测试的Python类?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08Python编程基础与实践示例
- 2024-11-07Python编程基础指南
- 2024-11-06Python编程基础入门指南
- 2024-11-06怎么使用python 计算两个GPS的距离功能-icode9专业技术文章分享
- 2024-11-06Python 基础编程入门教程
- 2024-11-05Python编程基础:变量与类型
- 2024-11-05Python编程基础:变量与类型
- 2024-11-04Python编程基础:变量与类型
- 2024-11-04Python编程基础
- 2024-11-04Python编程基础入门指南