Python:检查两个变量之间相同类型的最佳方法

时间:2019-07-09 16:39:32

标签: python python-3.x types isinstance

我正在检查两个变量是否在python 3.x中具有相同的类型。什么是最理想的方法?

采用以下示例:

class A():
    def __init__(self, x):
        self.x = x

class B(A):
    def __init__(self, x):
        x += 5
        super(B, self).__init__(x)

理想情况下,如果两个TrueA类型的变量相互比较,我想返回B。以下是一些无效的潜在解决方案:

>>> a = A(5)
>>> b = B(5)
>>>
>>> type(a) is type(b)
False
>>> isinstance(a, type(b))
False
>>> isinstance(b, type(a))
True

最后一个不理想,因为如中间示例所示,如果要检查的类型是变量类型的子类,则返回False

我尝试过的唯一可以覆盖所有基础的解决方案是:

>>> isinstance(a, type(b)) or isinstance(b, type(a))
True

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

该程序遍历所有__bases__提供的对象,并检查它们之间的公共交集(无object):

class A:
    def __init__(self, x):
        self.x = x

class B(A):
    def __init__(self, x):
        x += 5
        super(B, self).__init__(x)

class C(B):
    def __init__(self, x):
        self.x = x

class D:
    def __init__(self, x):
        self.x = x

class E(C, B):
    def __init__(self, x):
        self.x = x

a = A(5)
b = B(5)
c = C(5)
d = D(5)
e = E(5)

def check(*objs):
    def _all_bases(o):
        for b in o.__bases__:
            if b is not object:
                yield b
            yield from _all_bases(b)
    s = [(i.__class__, *_all_bases(i.__class__)) for i in objs]
    return len(set(*s[:1]).intersection(*s[1:])) > 0

print(check(a, b)) # True
print(check(a, c)) # True
print(check(a, d)) # False
print(check(a, e)) # True
print(check(b, c)) # True
print(check(b, d)) # False
print(check(b, e)) # True
print(check(e, d)) # False
print(check(a, b, c)) # True
print(check(a, b, c, e)) # True
print(check(a, b, c, d)) # False
print(check('string1', 'string2')) # True

答案 1 :(得分:0)

鉴于评估if user_type.lower() in ["yes", "y"]: 后代之间兼容性的既定目标,我认为您可能使问题变得过于复杂。至少在rich comparison方面,Python已经为您完成了此检查。根据文档:

  

如果操作数是不同类型的,并且右侧操作数的类型是左侧操作数类型的直接或间接子类,则右侧操作数的反射方法具有优先权,否则左侧操作数的方法具有优先权。不考虑虚拟子类化。

这意味着您要做的就是在A中实现运算符。如果任何后代需要添加功能,则应该这样做。这是一个示例:

A