Вы должны заставить print_entries
принять последовательность , а не список . Вот упрощенный пример, демонстрирующий типобезопасную версию вашего кода:
from typing import IO, List, Sequence, Union
class Open:
def __init__(self, account: int) -> None:
self.account = account
class Commodity: pass
Directives = Union[Open, Commodity]
def print_entries(entries: Sequence[Directives]) -> None:
for entry in entries:
print(entry)
accounts: List[Open] = [Open(1), Open(2), Open(3)]
print_entries(accounts)
Причина, по которой print_entries
принимает список типов ваших директив, заключается в том, что он вводит потенциальная ошибка в вашем коде - если бы print_entries
должен был сделать entries.append(Commodities())
, ваш список учетных записей больше не содержал бы только открытые объекты, нарушая безопасность типов.
Sequence - версия списка только для чтения и поэтому полностью обходит эту проблему, предоставляя ей меньше ограничений. (То есть List [T] является подклассом Sequence [T]).
Точнее, мы говорим, что Sequence является ковариантным типом: если, если у нас есть некоторые дочерний тип C, который подклассов родительского типа P (если P:> C), всегда верно, что Sequence [P]:> Sequence [C].
В отличие от списков invariant : List [P] и List [C] не будут иметь присущих друг другу отношений, и ни один из них не будет подклассами другого.
Вот сводная таблица различных видов отношений, общая информация c типы могут иметь:
| Foo[P] :> Foo[C] | Foo[C] :> Foo[P] | Used for
--------------------------------------------------------------------------------------
Covariant | True | False | Read-only types
Contravariant | False | True | Write-only types
Invariant | False | False | Both readable and writable types
Bivariant | True | True | Nothing (not type safe)