Python >= 3.8
As of Python3.8 there is typing.get_args
:
print( get_args( List[int] ) ) # (<class 'int'>,)
PEP-560 also provides __orig_bases__[n]
, which allows us the arguments of the nth generic base:
from typing import TypeVar, Generic, get_args
T = TypeVar( "T" )
class Base( Generic[T] ):
pass
class Derived( Base[int] ):
pass
print( get_args( Derived.__orig_bases__[0] ) ) # (<class 'int'>,)
Python >= 3.6
As of Python 3.6. there is a public __args__
and (__parameters__
) field.
For instance:
print( typing.List[int].__args__ )
This contains the generic parameters (i.e. int
), whilst __parameters__
contains the generic itself (i.e. ~T
).
Python < 3.6
Use typing_inspect.getargs
Some considerations
typing
follows PEP8. Both PEP8 and typing
are coauthored by Guido van Rossum. A double leading and trailing underscore is defined in as: "“magic” objects or attributes that live in user-controlled namespaces".
The dunders are also commented in-line; from the official repository for typing we
can see:
- "
__args__
is a tuple of all arguments used in subscripting, e.g., Dict[T, int].__args__ == (T, int)
".
However, the authors also note:
- "The typing module has provisional status, so it is not covered by the high standards of backward compatibility (although we try to keep it as much as possible), this is especially true for (yet undocumented) dunder attributes like
__union_params__
. If you want to work with typing types in runtime context, then you may be interested in the typing_inspect
project (part of which may end up in typing later)."
I general, whatever you do with typing
will need to be kept up-to-date for the time being. If you need forward compatible changes, I'd recommend writing your own annotation classes.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…