I'm doing some debugging and need to ensure instances of my class have a specific type, e.g. <type 'list'>, when type() is called.
The other option is redefining type() so it returns a different value when instances of my class are passed to it.
For example:
class Test:
def __str__(self):
return 'anything'
allows me to set my own value when the instance is treated as a string e.g. str(Test()). I want something similar for type(Test()):
class Test:
def __type__(self):
return type([])
(not valid)
One way to achieve this is to use meta classes and define types. Here's a simple example of how you can do that.
Meta class definition and inheritance
# 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
Tests
Let's test our 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'>
Now let's test our ObjectClass:
test = ObjectClass
print("mro: {} \ntype: {} \nrepr: {}".format(
test.__mro__,
type(test),
repr(test)
))
Displays:
mro: (<class '__main__.ObjectClass'>, <class 'object'>)
type: <class '__main__.TypeClass'>
repr: <class '__main__.ObjectClass'>
Finally, let's test our TestClass:
test = TestClass
print("mro: {} \ntype: {} \nrepr: {}".format(
test.__mro__,
type(test),
repr(test)
))
Displays:
mro: (<class '__main__.TestClass'>, <class '__main__.ObjectClass'>, <class 'object'>)
type: <class '__main__.TypeClass'>
repr: <class '__main__.TestClass'>
Answer to the question
So, here is an answer to your question. Although, it would be useful if you say why you're doing this. Perhaps there is a better way for implementing what you're trying to achieve here!
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()])
Which displays:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With