首页 > 解决方案 > 如何更改类型(对象)的结果?

问题描述

我正在使用一个 3rd-party 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它吗?

我知道正确的解决方案是让 3rd-party 模块使用isinstance,但不幸的是我无法改变它。

标签: pythonstringoop

解决方案


您可以劫持type第 3 方模块的内置函数。

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

# 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())

并且不要忘记告诉第 3 方修复他们的代码,以便您以后可以摆脱这种黑客攻击。


推荐阅读