Type Hints/Typing were introduced at #PEP-484 and described in more detail at #PEP-483. They look very familiar to Java Collections. Nevertheless they are a types that can be extended at your own purpose.
Documentation about typings is really straight-forward. I recommend you to check it out.
To The Point
NewType
You have types in python. Within them you can create a new types by making an inheritance.
I.e. to make new type from int you would normally do:
class NewIntType(int):
pass
But using typing you can do this:
from typing import NewType
NewIntType = NewType('NewIntType', int)
class NewIntInheritance(int):
pass
def sumUp(a: NewIntInheritance, b: NewIntInheritance) -> NewIntInheritance:
return a + b
print(sumUp(NewIntInheritance(1), NewIntInheritance(2)))
from typing import NewType
NewIntTyping = NewType('NewIntTyping', int)
def sumUpTyping(a: NewIntTyping, b: NewIntTyping) -> NewIntTyping:
return a + b
print(sumUpTyping(NewIntTyping(1), NewIntTyping(2)))
They will basically do the same. There is a difference. When you create a new type with inheritance, that you can use isinstance
with it.
This code shows the difference:
NewIntTyping = NewType('NewIntTyping', int)
def checkDifferenceInheritance(a: NewIntInheritance):
print(isinstance(a, NewIntInheritance))
def checkDifferenceTyping(a: NewIntTyping):
print(isinstance(a, NewIntTyping))
checkDifferenceInheritance(NewIntInheritance(1))
checkDifferenceTyping(NewIntTyping(1))
It will output with this:
True
Traceback (most recent call last):
File "test1.py", line 38, in <module>
checkDifferenceTyping(NewIntTyping(1))
File "test1.py", line 35, in checkDifferenceTyping
print(isinstance(a, NewIntTyping))
TypeError: isinstance() arg 2 must be a type or tuple of types
So using typing - you should avoid isinstance
or even issubclass
- as mentioned in TypeVar section
Type Aliasing
There is also aliasing of types within typing. You can create aliases from other types as documentation at type aliases says:
from typing import List
ListOfFloats = List[float]
print ListOfFloats([1.0, 2.0])
Where is this usefull ? Let's say you want to annotate your function to return List of numeric type of data.
You can do that with:
from typing import TypeVar
from typing import List
T = TypeVar('T', int, float)
def sort_list(elements) -> List[T]:
return sorted(elements)
print([1,2,20, 5, 4, 8, 3])
print(sort_list([1,2,20, 5, 4, 8, 3]))
Adding to this decorator that we have introduced at this article :
def decorator_annotation_parameters(function_wrapped):
def wrapper(*args, **kwargs):
annotations = function_wrapped.__annotations__
output = function_wrapped(*args, **kwargs)
returned_type = annotations.get('return')
for kwarg in kwargs:
kwarg_type = annotations.get(kwarg)
assert type(kwargs[kwarg]) == kwarg_type
if returned_type:
assert type(output) == returned_type
return output
return wrapper
We can create a checker that will check if the output value consists of Float-Lists and matches annotation output type.
Acknowledgements
Auto-promotion
Related links
- PEP 483 -- The Theory of Type Hints | Python.org
- PEP 484 -- Type Hints | Python.org
- GitHub - python/typing: Work related to PEP 484: typing.py (released via PyPI) and issue tracker
- python - What are the differences between type() and isinstance()? - Stack Overflow
- cpython/typing.py at 3.6 · python/cpython · GitHub
- Type Hints in Python 3.5 - cat /dev/brain
- Duck Typing vs. Goose Typing, Pythonic Interfaces :: tl;dr
- The best tool for the job: Duck typing vs Interfaces « Jason in a Nutshell
- Composition vs Inheritance
- python - Duck typing Vs class based Inheritance - Stack Overflow
Thanks!
That's it :) Comment, share or don't - up to you.
Any suggestions what I should blog about? Poke me at Twitter: @anselmos88.
See you in the next episode! Cheers!
Comments
comments powered by Disqus