如何更改类型(对象)的结果?

时间:2019-05-02 18:03:44

标签: python string oop

我正在使用一个第三方的Python模块,它做的事情很可怕,例如:

def foo(x):
    if type(x) is str:
        do_useful_thing()

我有一个继承str的类:

class mystr(str):
   ....

我想在foo()实例上调用mystr,但是由于type(mystr) != type(str)而失败。有什么办法可以让我的课程让type(mystr) == type(str)并因此foo接受吗?

我知道 right 解决方案是让第三方模块使用isinstance,但不幸的是我无法更改它。

3 个答案:

答案 0 :(得分:4)

您可以劫持第三方模块的内置type

因此,如果第三方代码是这样的:

# bar.py (a.k.a, crappy 3rd-party code)
def foo(x):
    if type(x) is str:
        return True
    return False

您可以这样写:

import bar

class MyStr(str):
    pass

# Returns False.... BOOO!
bar.foo(MyStr())

def fake_type(a):
    if isinstance(a, MyStr):
        return str
    else:
        return type(a)

bar.type = fake_type

# This should now return True :-)
bar.foo(MyStr())

别忘了告诉第三方修复他们的代码,以便以后可以摆脱这种黑客攻击。

答案 1 :(得分:4)

发表评论部分的共识作为答案:即使有可能做这种事情,这也是一个非常糟糕的主意。即使您有时工作,它也会导致奇怪的事情在其他地方中断。

正确的答案是与第三方库的作者联系,并尝试与他们解决。或者,如果可能的话,派生该库并维护自己的不受此限制的版本。

答案 2 :(得分:1)

这将取决于您如何对str进行子类化,但是您可能需要做的只是暂时将类型转换回str ...

class mystr(str):
    def has_e(self):
        if 'e' in self:
            print('True')

def foo(value):
    if type(value) == str:
        print('You Rock')
    else:
        print('You Roll')

if __name__=='__main__':
    a = mystr('hi mom')
    a.has_e()
    foo(str(a))