Повышение TypeError при создании NamedTuple с вводом - PullRequest
1 голос
/ 26 апреля 2019

Как я могу сделать свой именованный кортеж, чтобы вызвать исключение TypeError?

from typing import NamedTuple

class Foo(NamedTuple):

    bar : int     
    sla : str

Однако, когда я пытаюсь создать экземпляр именованного кортежа, используя недопустимые типы, исключение не возникает

test = Foo('not an int',3)

#i can even print it

print(test.bar)
´´´

Ответы [ 2 ]

1 голос
/ 26 апреля 2019

Модуль typing реализует подсказки типа, как определено в PEP 484 . Подсказки типа - это именно то, что подразумевает название ... они являются "подсказками". Они не влияют на выполнение кода Python самостоятельно. Согласно документу PEP 484:

Хотя эти аннотации доступны во время выполнения через обычные Атрибут annotations , проверка типов во время выполнения не выполняется. Вместо этого предложение предполагает наличие отдельного автономного средство проверки типов, которое пользователи могут добровольно запускать поверх своего исходного кода. По сути, такая проверка типов действует как очень мощный линтер.

Таким образом, вам понадобится дополнительный код или инструмент, чтобы использовать информацию о типе, которую вы добавили в свой код, чтобы либо сообщить вам заранее, что ваш код нарушает подсказки типа, либо сообщить вам во время выполнения кода. Сам модуль typing не обеспечивает эту функциональность.

Я поместил ваш код в мою PyCharm IDE, и IDE помечает строковый параметр, который вы передаете конструктору, как нарушение подсказок типа, заявляя: "Ожидаемый тип 'int', получен 'str' вместо ". Таким образом, PyCharm IDE является одним из таких инструментов, который использует подсказки типов. PyCharm, однако, очень рад запустить код и не генерирует ошибок.

0 голосов
/ 26 апреля 2019
from typing import NamedTuple


class Foo(NamedTuple):
    bar: int
    sla: str

    def check_type(self):
        for field, field_type in self._field_types.items():
            if not isinstance(getattr(self, field), field_type):
                raise TypeError('{} must be {}'.format(field, field_type))
        return self


if __name__ == '__main__':
    test = Foo('not an int', 3).check_type()
    print(test.bar)

Вы можете добавить дополнительный метод для проверки. Приведенный выше код вызовет TypeError, если не совпадает.

...