如何重新定义Python类实例的type()?

如何重新定义Python类实例的type()?,python,python-2.7,class,types,instance,Python,Python 2.7,Class,Types,Instance,我正在进行一些调试,需要确保在调用type()时类的实例具有特定的类型,例如 另一个选项是重新定义type(),以便在将类的实例传递给它时返回不同的值 例如: class Test: def __str__(self): return 'anything' 当实例被视为字符串时,允许我设置自己的值,例如str(Test())。我想要类似的类型(Test()): (无效)您可以,但我不建议您这样做: class A(object): def __init__(se

我正在进行一些调试,需要确保在调用
type()
时类的实例具有特定的类型,例如

另一个选项是重新定义
type()
,以便在将类的实例传递给它时返回不同的值

例如:

class Test:
    def __str__(self):
        return 'anything'
当实例被视为字符串时,允许我设置自己的值,例如
str(Test())
。我想要类似的
类型(Test())


(无效)

您可以,但我不建议您这样做:

class A(object):
    def __init__(self):
        self.__class__.__name__ = 'B'

print type(A())  # <class 'B'>
print type(A()) == B  # False, since it's actually not a type B
print type(A()).__name__ == 'B'  # True, since the name is 'B'
编辑:回答问题的另一部分:如果要覆盖类型,可以这样做:

class A(object):
    pass

def x(x):
    return 'test'

__builtins__.type = x

print type(A())  # test

我的印象是,您正在尝试做错误的事情,可能是因为您以前使用的是静态类型语言

在python中,永远不应该检查类型,而应该检查行为

也许你需要一些类似的东西:

import collections

if isinstance(theElement, collections.Iterable):
    # iterable
else:
    # not iterable

实现这一点的一种方法是使用元类并定义类型。下面是一个简单的例子,说明如何做到这一点

元类定义和继承

# Meta class
class TypeClass(type):
        def __new__(cls, *args, **kwargs):
                return super(TypeClass, cls).__new__(cls, *args, **kwargs)

        def __init__(self, *args, **kwargs):
                super(TypeClass, self).__init__(*args, **kwargs)


# Class directly inheriting from the meta class.
class ObjectClass(metaclass=TypeClass):
        pass


# Class that has indirectly inherited from the meta class.
class TestClass(ObjectClass):
        pass
测试

让我们测试一下我们的
TypeClass

test = TypeClass
print("mro: {} \ntype: {} \nrepr: {}".format(
          test.__mro__,
          type(test),
          repr(test)
      ))

mro: (<class '__main__.TypeClass'>, <class 'type'>, <class 'object'>) 
type: <class 'type'> 
repr: <class '__main__.TypeClass'>
test = ObjectClass
print("mro: {} \ntype: {} \nrepr: {}".format(
          test.__mro__,
          type(test),
          repr(test)
     ))
test = TestClass

print("mro: {} \ntype: {} \nrepr: {}".format(
          test.__mro__, 
          type(test), 
          repr(test)
      ))
显示:

mro: (<class '__main__.ObjectClass'>, <class 'object'>) 
type: <class '__main__.TypeClass'> 
repr: <class '__main__.ObjectClass'>
mro: (<class '__main__.TestClass'>, <class '__main__.ObjectClass'>, <class 'object'>) 
type: <class '__main__.TypeClass'> 
repr: <class '__main__.TestClass'>
显示:

mro: (<class '__main__.ObjectClass'>, <class 'object'>) 
type: <class '__main__.TypeClass'> 
repr: <class '__main__.ObjectClass'>
mro: (<class '__main__.TestClass'>, <class '__main__.ObjectClass'>, <class 'object'>) 
type: <class '__main__.TypeClass'> 
repr: <class '__main__.TestClass'>
其中显示:

mro: (<class '__main__.TestClass'>, <class '__main__.TypeClass'>, <class 'list'>, <class 'object'>) 
type: <class 'type'> 
repr: <class '__main__.TestClass'>

('test3', True) ('test6', True) ('test4', False) ('test7', False) ('test5', False) ('test2', False) ('test1', True) ('test8', True)
mro:(,)
类型:
报告:
('test3',True)('test6',True)('test4',False)('test7',False)('test5',False)('test2',False)('test1',True)('test8',True)

你不能。您确定需要匹配该类型吗?子类不行?换句话说,请告诉我们您认为需要该类型的原因,这听起来很像。我正在调试使用type()的代码,我需要“愚弄”它,以便我可以使用自己的对象而不是列表。此外,我还想知道一些理论上的原因和理解。如果代码明确预期,您可能会被卡住:原始代码应该是duck-typed。这实际上不会以编程方式影响类型。它改变了打印的内容,但是如果你执行
打印类型(A())==B
,它将打印
False
。我想这就是他想要的?我可能误解了。他说,“需要确保我的类的实例有一个特定的类型,例如。”。在你的情况下,他们真的没有。(他们确实有一种类型名为
)你的答案可能是最接近被问到的答案,但我认为它不太合适。他仍然可以这样使用
类型(a())。u name_uu==“B”#True
,这取决于他想要它做什么。。。但你可能是对的,这不会为他解决问题……这是真的。我同意你的看法。那仍然是类型检查;您只是在检查元素是否是另一个(虚拟)超类的实例。我正在调试使用type()的代码,我需要“愚弄”它。@Qgenerator这个代码在库中是您无法修复的吗?开源python库非常开放,可以接收pull请求。我怀疑你是否能够愚弄
type()
,因为这是一个相当低的级别,如果你成功地做到了,你最终会破坏你的另一个类,因为它会开始相信这是另一个东西。出于调试的目的,我实际上不会保留丑陋的代码。我如何使用它来生成type(instance)=type([])我会把它添加到我答案的底部。好了!我将其添加到现有答案中!但说真的,告诉我你想做什么。可能有更好的方法,因为这很尴尬。坦白地说,我已经编程15年了,这是我第一次看到需要这样的实现,尤其是现有类型的实现!
mro: (<class '__main__.TestClass'>, <class '__main__.TypeClass'>, <class 'list'>, <class 'object'>) 
type: <class 'type'> 
repr: <class '__main__.TestClass'>

('test3', True) ('test6', True) ('test4', False) ('test7', False) ('test5', False) ('test2', False) ('test1', True) ('test8', True)