微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 issubclass 测试类型返回不一致的结果

如何解决使用 issubclass 测试类型返回不一致的结果

我有一个没有属性class A,我测试它是否是 typing.Container 的子类。正如预期的那样,该测试失败了。

在单独的测试中,我将 __contains(self,k)__ 属性添加到 A,并测试它是否是 typing.Container 的子类,并且该测试通过。

现在奇怪的是,如果我测试 A 是否是 typing.Conainer 的子类,然后添加 __contains(self,k)__ 属性,然后再次测试 A 是否是一个typing.Container 的子类,该测试失败。

发生了什么导致最后一次测试失败,即使 A 确实具有 __contains__(self,k)__ 属性

import pytest
from typing import Container

@pytest.fixture
def A():
    class A:...
    return A

def test_notsubclass(A):
    # passes
    assert not issubclass(A,Container)

def test_addcontains(A):
    # passes
    def __contains__(self,k): ...
    setattr(A,'__contains__',__contains__)
    assert issubclass(A,Container)

def test_first_then_add_contains(A):
    # passes
    assert not issubclass(A,Container)
    def __contains__(self,__contains__)

    # fails
    assert issubclass(A,Container)

解决方法

许多 typing 类型的运行时表示是围绕相应 collections.abc 类型的包装器。 For example,typing.Container is a generic "alias" of collections.abc.Container:

Container = _alias(collections.abc.Container,1)

顾名思义,collections.abc 成员源自 abc.ABC/abc.ABCMeta。由于 ABC 子类/实例检查可能很昂贵,abc.ABCMeta has an optimisation to cache subclass checks

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。