'Python type hint for (any) class
I want to type hint the following function:
def get_obj_class(self) -> CLASS_TYPE:
return self.o.__class__
CLASS_TYPE
should denoteclass
es.self.o
could be of any type determined at runtime.
On a similar note, if I have a function f(cls: CLASS_TYPE)
which returns an instance of cls
, is there a way to type hint the return value appropriately?
Solution 1:[1]
I'd recommend using a combination of TypeVar
, to indicate that your self.o
value could be any arbitrary type, and Type
, in the following way:
from typing import TypeVar, Type
T = TypeVar('T')
class MyObj:
def __init__(self, o: T) -> None:
self.o = o
def get_obj_class(self) -> Type[T]:
return type(self.o)
def accept_int_class(x: Type[int]) -> None:
pass
i = MyObj(3)
foo = i.get_obj_class()
accept_int_class(foo) # Passes
s = MyObj("foo")
bar = s.get_obj_class()
accept_int_class(bar) # Fails
If you want the type of o
to be even more dynamic, you could explicitly or implicitly give it a type of Any
.
Regarding your latter question, you'd do:
def f(cls: Type[T]) -> T:
return cls()
Note that you need to be careful when instantiating your class -- I don't remember what Pycharm does here, but I do know that mypy currently does not check to make sure you're calling your __init__
function correctly/with the right number of params.
(This is because T could be anything, but there's no way to hint what the constructor ought to look like, so performing this check would end up being either impossibly or highly difficult.)
Solution 2:[2]
For Python >=3.7, use type
(see also PEP 585):
def get_obj_class(self) -> type:
return self.o.__class__
For Python <3.7, use typing.Type
:
def get_obj_class(self) -> typing.Type:
return self.o.__class__
Solution 3:[3]
What about typing.Type
?
That seems to fit since __class__
should always return a type.
import typing
def test(t: object) -> typing.Type:
return t.__class__
class Dummy(object):
pass
test(Dummy())
To your second question: that should be a generic.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Michael0x2a |
Solution 2 | Mateen Ulhaq |
Solution 3 | Mateen Ulhaq |