[Python] I searched for various types! (Typing)

Introduction

Starting with python3.5, python also incorporates the concept of type hints. To use it, use the built-in type or use ʻimport typing, and use mypy` to check the type.

About mypy

Installation

First, install the package to use mypy.

$ pip install mypy

setting file

Create mypy.ini as follows and enter the setting information there.

mypy.ini


[mypy]
python_version = 3.8
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
disallow_incomplete_defs = True
check_untyped_defs = True
pretty = True

[mypy-django.*]
ignore_missing_imports = True

See here (https://mypy.readthedocs.io/en/latest/config_file.html) for what you can configure.

Various usages

Built-in type

The built-in type can be used as it is.

num: int = 1
float_num: float = 1.11
is_something: bool = True
text: str = 'hoge'
byte_str: bytes = b'fuga'
arr: list = [0, 1, 2, 3]

Any type

If you don't know what type goes into the variable, use ʻAny`. If this type is specified, no type checking will be done.

something: Any = Something()

The base class of all types, ʻobject, can be used in the same way, but ʻobject is used to indicate that a value can be used as any type in a type-safe way, and ʻAny` is. Used to indicate that a value is dynamically typed.

Dict type

If you use the dictionary type, use typing.Dict.

dictionary: Dict[str, int] = {'hoge': 1, 'fuga': 2}

Tuple type

If you want to use tuple types, use typing.Tuple.

something: Tuple[str, int] = ('hoge', 1)

Set type

If you want to use the set type, use typing.Set. The set type is a collection of unique items.

something: Set[int] = {6, 7}

Sequence type

If you want to use the sequence type, use typing.Sequence. The sequence type is a data structure for processing in order (sequential).

something: Sequence = [0, 1, 2]

Iterator type

If you want to use the iterator type, use typing.Iterator. The iterator type must be an iterable class and have __iter__ ().

something: Iterator = IterableClass()

Mapping type

If you want to use the mapping type, use typing.Mapping. The mapping type is a data structure for performing arbitrary key search, and is an Immutable type.

something: Mapping[str, int] = {'hoge': 1, 'fuga': 2}

Union type

If you want to use a union type, use typing.Union. Union types allow you to specify multiple types.

something_mapping: Mapping[str, int] = {'hoge': 1, 'fuga': 2}
something_union: Union[int, None] = something_mapping.get('hoge') # 1
something_union: Union[int, None] = something_mapping.get('piko') # None

Optional type

typing.Optional is an image in which None of type typing.Union is always selected.

something_mapping: Mapping[str, int] = {'hoge': 1, 'fuga': 2}
something_optional: Optional[int] = something_mapping.get('hoge') # 1
something_optional: Optional[int] = something_mapping.get('piko') # None

Callable type

If you want to use a function, use typing.Callable.

def something() -> bool:
    return True

something_callable: Callable = something

Literal type

Use typing.Literal if you want to ensure that you only get a fixed value.

mode: Literal['r', 'rb', 'w', 'wb'] = 'r' # OK
mode: Literal['r', 'rb', 'w', 'wb'] = 'a' # NG

AnyStr type

Use typing.AnyStr if you want it to be used by a function that allows any kind of string without mixing it with other kinds of strings.

def concat(a: AnyStr, b: AnyStr) -> AnyStr:
    return a + b

concat(u"foo", u"bar")  #OK unicode is output
concat(b"foo", b"bar")  #OK bytes are output
concat(u"foo", b"bar")  #An error will occur because NG unicode and bytes are mixed.

Type alias

You can define the old type with any type name.

Vector = List[float]
ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

NewType Use typing.NewType to create different types.

UserId = NewType('UserId', int)
some_id = UserId(524313)

Generics

To use generic types:

T = TypeVar('T')

#This is the Generic function
#Any type can be used for l Sequence type
def first(l: Sequence[T]) -> T:
    return l[0]

User-defined generic types can be used as follows:

T = TypeVar('T')

class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value

    def set(self, new: T) -> None:
        self.log('Set ' + repr(self.value))
        self.value = new

    def get(self) -> T:
        self.log('Get ' + repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info('%s: %s', self.name, message)

logger: LoggedVar[str] = LoggedVar('hoge', 'Test', Logger())
logger.get() #T is treated as str type

Cast (typing.cast)

Once you want to change the defined type, cast it using typing.cast. In order to make the process as fast as possible, we intentionally inspect nothing at runtime.

a = [4]
b = cast(List[int], a)
c = cast(List[str], a) # [4]Is never a string, so if you want to convert it, add the conversion process yourself

Constant (typing.Final)

If you want to use constants, use typing.Final.

SOMETHING: Final[str] = 'Something'

in conclusion

How was that? I think that you can create a stronger application by making full use of the type. However, please note that specifying the type does not speed up the special processing. Some of them haven't actually been seen to work, so if you find something wrong, please let us know.

reference

https://docs.python.org/ja/3/library/typing.html

Recommended Posts

[Python] I searched for various types! (Typing)
I searched for prime numbers in python
I searched for CD commands.
Python typing
I wrote unit tests for various languages
2016-10-30 else for Python3> for:
python [for myself]
I made a python dictionary file for Neocomplete
[Python] I tried substituting the function name for the function name
vprof --I tried using the profiler for Python
[python] Create a list of various character types
I searched for railway senryu from the data
I tried playing a typing game in Python
I started python
Python dynamic typing
I tried python programming for the first time.
I searched for the skills needed to become a web engineer in Python
When I searched for "as a Service" from AaaS to ZaaS, I saw various services.
What I got into Python for the first time
I tried Python on Mac for the first time.
I tried pipenv and asdf for Python version control
I made a VM that runs OpenCV for Python
I tried python on heroku for the first time
Mongodb Shortest Introduction (2) I searched for tens of thousands
Python Exercise for Beginners # 1 [Basic Data Types / If Statements]
[Python] I made a classifier for irises [Machine learning]
I searched for the contents of CloudWatch Logs Agent
About Python for loops
Python basics ② for statement
I tried Python> autopep8
About Python, for ~ (range)
python textbook for beginners
Refactoring tools for Python
I implemented Python Logging
python for android Toolchain
[Python] Sort collection types
I tried Python> decorator
Why I chose Python
OpenCV for Python beginners
Organize types in Python
I compared Python more-itertools 2.5 → 2.6
Various processing of Python
Install Python (for Windows)
[Python] for statement error
Python environment for projects
I searched about Pynamodb
I was hooked for 2 minutes with the Python debugger pdb
I tried to make various "dummy data" with Python faker
I tried various methods to send Japanese mail with Python
Try to display various information useful for debugging with python
I searched for works that are highly evaluated by Naro
I measured various methods of interprocess communication in multiprocessing of python3
Which should I study, R or Python, for data analysis?
I didn't know how to use the [python] for statement
I created a class in Python and tried duck typing
Miscellaneous notes that I tried using python for the matter