[英]How can I redefine the type() of instances of my Python class?
我正在做一些调试,需要确保在调用type()
时类的实例具有特定的类型,例如<type 'list'>
。
另一个选项是重新定义type()
以便在将我的类的实例传递给它时返回一个不同的值。
例如:
class Test:
def __str__(self):
return 'anything'
当实例作为字符串处理时,例如str(Test())
,我可以设置自己的值。 我想要对type(Test())
类似的东西:
class Test:
def __type__(self):
return type([])
(无效)
您可以,但我不建议您这样做:
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 B(object):
def x(self):
return 'b'
class A(object):
def __init__(self):
self.__class__ = B
def x(self):
return 'a'
print A().x() # 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'>
现在让我们测试一下ObjectClass
:
test = ObjectClass
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'>
最后,让我们测试一下我们的TestClass
:
test = TestClass
print("mro: {} \ntype: {} \nrepr: {}".format(
test.__mro__,
type(test),
repr(test)
))
显示:
mro: (<class '__main__.TestClass'>, <class '__main__.ObjectClass'>, <class 'object'>)
type: <class '__main__.TypeClass'>
repr: <class '__main__.TestClass'>
回答问题
因此,这是您问题的答案。 不过,如果您说出这样做的原因,将很有用。 也许有一种更好的方法可以在这里实现您要实现的目标!
class TypeClass(list):
def __new__(cls, args):
return super(TypeClass, cls).__new__(cls, args)
def __init__(self, args):
super(TypeClass, self).__init__(args)
# class ObjectClass(metaclass=TypeClass):
# pass
class TestClass(TypeClass):
pass
test = TestClass
print("mro: {} \ntype: {} \nrepr: {}".format(
test.__mro__,
type(test),
repr(test)
))
tests = {
'test1': isinstance(TestClass, type(list)),
'test2': isinstance(TestClass, list),
'test3': type(TestClass) is type(list),
'test4': type(TestClass) is list,
'test5': type(TestClass) is type([]),
'test6': type(TestClass) == type(list),
'test7': type(TestClass) == type([]),
'test8': type(TestClass) == type(type([]))
}
print('\n', *[item for item in tests.items()])
显示:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.