如何使用 __subclasscheck__ 魔术方法?

Posted

技术标签:

【中文标题】如何使用 __subclasscheck__ 魔术方法?【英文标题】:How to use the __subclasscheck__ magic method? 【发布时间】:2016-04-09 23:33:39 【问题描述】:

我们怎样才能让一个类对他的子类撒谎?

在阅读了doc 之后,我尝试了这个:

>>> class AllYourBase(type):
...     @classmethod
...     def __subclasscheck__(cls, other):
...         return True
...     
>>> class AllYour(object):
...     __metaclass__ = AllYourBase

现在,这个班级应该报告你所有的基地都属于他。

但它不起作用:

>>> issubclass(AllYour, int)
False

为什么不呢?

【问题讨论】:

【参考方案1】:

如果您希望AllYour 声称是每个类的子类,那是不可能的。 __subclasscheck__ 在另一个方向工作。

如果您希望 AllYour 声明每个类都继承它,请删除 @classmethod 装饰器,并在 issubclass 调用中切换参数。您在元类上定义的特殊方法不需要特殊修饰。

【讨论】:

确实,@classmethod 意味着 元类 将被传递给 __subclasscheck__()。您需要一个常规实例方法(该实例是 AllYour 类)。 移除这个装饰器并没有改变行为 @wim:仔细检查后,您的issubclass 调用中的参数似乎顺序错误。 Fixing that produces a result of True. 如果你想要一个声称是每个类的子类的类,而不是声称每个类都是它的子类,那是不可能的。 哦,对了。我想要另一种方式。我们可以猴子补丁type.__subclasscheck__ 吗? @wim:也许如果你以正确的方式使用 ctypes。不过,它真的很脆弱。我尝试使用gc.getreferents(type.__dict__)[0] 修补type.__subclasscheck__ 以通过dict_proxy,但它只会使Python 崩溃。

以上是关于如何使用 __subclasscheck__ 魔术方法?的主要内容,如果未能解决你的问题,请参考以下文章

php啥是魔术方法

PHP魔术方法和魔术变量总结

python之使用魔术方法__getitem__和__len__

php魔术方法__tostring

PHP的魔术常量和魔术方法

PHP之魔术常量