c++找不到标识符_『灌水』原来 Python 的 issubclass 是找 MRO 的

16151209de191da349e90df018f1fda6.png

正在给自己的游戏补测试,需要 Mock,也没有方便的办法能让 mypy 接受我的 mock 对象,于是想了一个奇技淫巧:

class MockMeta(type): 
    def mro(cls): 
        bases = cls.__bases__ 
        assert len(bases) == 1 
        return [cls, object] 

class A(object):
    def foo(self):
        print('foo')

class C(A, metaclass=MockMeta):
    def baz(self):
        print('baz')

希望这样能让系统以为我的 CA的 subclass 但是实际上不会有 A 的方法能够被 C访问(希望 Mock 对象能过类型检查,同时不会不小心调用到实际的 A上的代码)

然而……

In [7]: C()                                                                                                                                                                                                         
Out[7]: <__main__.C at 0x7fe5d2ddfb00>

In [8]: C.mro()                                                                                                                                                                                                     
Out[8]: [__main__.C, object]

In [9]: issubclass(C, A)                                                                                                                                                                                            
Out[9]: False

In [10]: issubclass(A, C)                                                                                                                                                                                           
Out[10]: False

In [11]: C.__bases__                                                                                                                                                                                                
Out[11]: (__main__.A,)

处于好奇看了下 CPython 的源码(题图),妈蛋居然就是找 MRO 的,找不到 MRO 才找 __bases__

应该看看 Abstract Base Class ?上班去了,晚上再折腾。


UPDATE

成功地骗过了 mypy,所以算是达成目标了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值