рдкрд╛рдпрдерди рдореЗрдВ рд╕реНрдереИрддрд┐рдХ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рдХреБрдЫ рдиреБрдХрд╕рд╛рди


рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдзреАрд░реЗ-рдзреАрд░реЗ рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрднреНрдпрд╕реНрдд рд╣реЛ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдкрд╛рдпрдерди рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди рд╣реИрдВ: рдЙрдиреНрд╣реЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ ( рдкреАрдИрдкреА 484 ) рдХреЗ рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рджреЛ рд░рд┐рд▓реАрдЬ (3.5) рд╡рд╛рдкрд╕ рд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЕрдВрддрд┐рдо рд░рд┐рд▓реАрдЬ (3.6) рдореЗрдВ рдЪрд░ ( рдкреАрдИрдкреА 526 ) рдХреЗ рд▓рд┐рдПред


рдЪреВрдВрдХрд┐ рдпреЗ рджреЛрдиреЛрдВ PEP MyPy рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдереЗ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЗрд╕ рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди рд╕рд╛рдВрд╕рд╛рд░рд┐рдХ рдЦреБрд╢рд┐рдпрд╛рдБ рдФрд░ рд╕рдВрдЬреНрдЮрд╛рдирд╛рддреНрдордХ рдЕрд╕рдВрдЧрддрд┐рдпрд╛рдБ рдореБрдЭреЗ рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рд╡рд╛рддреА рд╣реИрдВ , рд╕рд╛рде рд╣реА рд╕рд╛рде рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рднреАред


рд╡рд┐рд╕реНрдордпрд╛рджрд┐рдмреЛрдзрдХ: рдореИрдВ рдЕрдЬрдЧрд░ рдореЗрдВ рд╕реНрдереИрддрд┐рдХ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдпрд╛ рд╣рд╛рдирд┐рдХрд╛рд░рдХрддрд╛ рдХрд╛ рд╕рд╡рд╛рд▓ рдирд╣реАрдВ рдЙрдард╛рддрд╛ред рдореИрдВ рдХреЗрд╡рд▓ рдЙрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреБрдХрд╕рд╛рдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рдореИрдВ рдПрдХ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдЖрдпрд╛ рдерд╛ред

рдЬреЗрдирд░рд┐рдХ (рдЯрд╛рдЗрдкрд┐рдВрдЧред рдЬреЗрдирд░рд┐рдХ)


рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ List[int] , Callable[[int, str], None] List[int] рдЬреИрд╕реЗ рдХреБрдЫ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИред
рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ рдЬрдм рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рддрд╛ рд╣реИ:


 T = ty.TypeVar('T') class A(ty.Generic[T]): value: T A[int]().value = 'str' # error: Incompatible types in assignment # (expression has type "str", variable has type "int") 

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ?
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдПрдХ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рдирд╛, рдФрд░ рдлрд┐рд░ рдЙрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рд╣реИ?


 T = ty.TypeVar('T') class Gen(Generic[T]): value: T ref: Type[T] def __init__(self, value: T) -> None: self.value = value self.ref = type(value) 

рдХрд┐рд╕реА рддрд░рд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрдХреВрд▓ рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдРрд╕рд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?


 b = Gen[A](B()) 

рдЗрд╕ рдкреНрд░рд╢реНрди рдХреЗ рдЙрддреНрддрд░ рдХреА рддрд▓рд╛рд╢ рдореЗрдВ, рдореИрдВ рдереЛрдбрд╝рд╛ typing , рдФрд░ рдХрд╛рд░рдЦрд╛рдиреЛрдВ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдбреВрдм рдЧрдпрд╛ред

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЬреЗрдиреЗрд░рд┐рдХ рд╡рд░реНрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕реЗ __origin_class__ рд╡рд┐рд╢реЗрд╖рддрд╛ __origin_class__ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ __args__ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЯрдкрд▓ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, __new__ рд╕реЗ, рд╕рд╛рде рд╣реА __new__ , рдЗрд╕ рддрдХ __new__ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдпрд╣ __call__ рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдФрд░ рдЪрд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ Generic рдХреЗ рдЙрдкрд╡рд░реНрдЧ рдХреЗ рдЖрд░рдВрдн рдХреЗ рд╕рдордп Generic рдпрд╣ рдПрдХ рдЕрдиреНрдп _GenericAlias рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрдВрддрд┐рдо рдкреНрд░рдХрд╛рд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рддреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЖрд░рдореНрдн рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдЙрд╕рдХреЗ __getithem__ рд╕рднреА рддрд░реАрдХреЛрдВ рд╕рд╣рд┐рдд, рдпрд╛ рдЬрдм __getithem__ рдкрд░ __getithem__ рдХрд┐рдпрд╛ __getithem__ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╕рдордп рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред


рд╣рдордиреЗ рдЗрд╕ рдХрдЪрд░реЗ рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛, рдФрд░ рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╕рдорд╛рдзрд╛рди рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ред

рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рдПрдХ рдЫреЛрдЯрд╛ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рд▓рд┐рдЦрд╛ рдЬреЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ:


 def _init_obj_ref(obj: 'Gen[T]') -> None: """Set object ref attribute if not one to initialized arg.""" if not hasattr(obj, 'ref'): obj.ref = obj.__orig_class__.__args__[0] # type: ignore class ValueHandler(Generic[T]): """Handle object _value attribute, asserting it's type.""" def __get__(self, obj: 'Gen[T]', cls: Type['Gen[T]'] ) -> Union[T, 'ValueHandler[T]']: if not obj: return self _init_obj_ref(obj) if not obj._value: obj._value = obj.ref() return obj._value def __set__(self, obj: 'Gen[T]', val: T) -> None: _init_obj_ref(obj) if not isinstance(val, obj.ref): raise TypeError(f'has to be of type {obj.ref}, pasted {val}') obj._value = val class Gen(Generic[T]): _value: T ref: Type[T] value = ValueHandler[T]() def __init__(self, value: T) -> None: self._value = value class A: pass class B(A): pass b = Gen[A](B()) b.value = A() b.value = int() # TypeError: has to be of type <class '__main__.A'>, pasted 0 

рдмреЗрд╢рдХ, рдкрд░рд┐рдгрд╛рдо рдореЗрдВ, рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╕рд╛рд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред


[UPD]: рд╕реБрдмрд╣ рдореИрдВрдиреЗ typing рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╕рд░рд▓:


 import typing as ty T = ty.TypeVar('T') class A(ty.Generic[T]): # __args are unique every instantiation __args: ty.Optional[ty.Tuple[ty.Type[T]]] = None value: T def __init__(self, value: ty.Optional[T]=None) -> None: """Get actual type of generic and initizalize it's value.""" cls = ty.cast(A, self.__class__) if cls.__args: self.ref = cls.__args[0] else: self.ref = type(value) if value: self.value = value else: self.value = self.ref() cls.__args = None def __class_getitem__(cls, *args: ty.Union[ty.Type[int], ty.Type[str]] ) -> ty.Type['A']: """Recive type args, if passed any before initialization.""" cls.__args = ty.cast(ty.Tuple[ty.Type[T]], args) return super().__class_getitem__(*args, **kwargs) # type: ignore a = A[int]() b = A(int()) c = A[str]() print([a.value, b.value, c.value]) # [0, 0, ''] 

[UPD]: typing рдбреЗрд╡рд▓рдкрд░ рдЗрд╡рд╛рди рд▓реЗрд╡рд┐рдВрд╕реНрдХреА рдиреЗ рдХрд╣рд╛ рдХрд┐ рджреЛрдиреЛрдВ рд╡рд┐рдХрд▓реНрдк рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд░реВрдк рд╕реЗ рдЯреВрдЯ рд╕рдХрддреЗ рд╣реИрдВред


рд╡реИрд╕реЗ рднреА, рдЖрдк рдЬреЛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╢рд╛рдпрдж __class_getitem__ рдереЛрдбрд╝рд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдХрдо рд╕реЗ рдХрдо __class_getitem__ рдПрдХ рдкреНрд░рд▓реЗрдЦрд┐рдд рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдзрд┐ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЬреЗрдирд░рд┐рдХ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рд╣реИ)ред

рдХрд╛рд░реНрдп рдФрд░ рдЙрдкрдирд╛рдо


рд╣рд╛рдВ, рдЬреЗрдирд░рд┐рдХ рдмрд┐рд▓реНрдХреБрд▓ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ:
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдХрд╣реАрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХрд╛ рдПрдиреЛрдЯреЗрд╢рди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕рд╣рд╕рдВрдпреЛрдЬрдХ рд╕реЗ рд╡рд┐рдкрд░реАрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:


 class A: pass class B(A): pass def foo(arg: 'A') -> None: #   A  B ... def bar(f: Callable[['A'], None]): #       A ... 

рдФрд░ рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рддрд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рд╢рд┐рдХрд╛рдпрдд рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓ рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдирд╛рдореЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ:


 TA = TypeVar('TA', bound='A') def foo(arg: 'B') -> None: #   B   ... def bar(f: Callable[['TA'], None]): #     A  B ... 

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рдкрд░ рдЕрдиреБрднрд╛рдЧ рдХреЛ рдзреНрдпрд╛рди рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ред


рдкрд┐рдЫрдбрд╝реА рдЕрдиреБрдХреВрд▓рддрд╛


рдпрд╣ рдЗрддрдирд╛ рдЧрд░реНрдо рдирд╣реАрдВ рд╣реИ: рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ 3.7 Generic ABCMeta рдХрд╛ рдПрдХ рдЙрдкрд╡рд░реНрдЧ рд╣реИ, рдЬреЛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рд╣реИред рдпрд╣ рдЦрд░рд╛рдм рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рдХреЛ рддреЛрдбрд╝рддрд╛ рд╣реИ рдпрджрд┐ рдпрд╣ 3.6 рдкрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИред


рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо (Stuctural Suptyping)


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдореИрдВ рдмрд╣реБрдд рдЦреБрд╢ рдерд╛: рдЗрдВрдЯрд░рдлреЗрд╕ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдП рдЧрдП рдереЗ! рдЗрдВрдЯрд░рдлреЗрд╕ рдХреА рднреВрдорд┐рдХрд╛ typing_extensions рдореЙрдбреНрдпреВрд▓ рд╕реЗ Protocol рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдХреА typing_extensions рд╣реИ, рдЬреЛ @runtime рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ, рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡рд░реНрдЧ рд╕реАрдзреЗ рдЗрдирд╣реЗрд░рд┐рдЯреЗрдВрд╕ рдХреЗ рдмрд┐рдирд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред MyPy рдХреЛ рдПрдХ рдЧрд╣рд░реЗ рд╕реНрддрд░ рдкрд░ рднреА рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВрдиреЗ рдХрдИ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░рд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдЬреНрдпрд╛рджрд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рджреЗрдЦрд╛ред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдирд╛рдо рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рддрд░реНрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд┐рдП рдмрд┐рдирд╛, рдЕрдиреБрдкрд╛рд▓рди рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:


 import typing as ty import typing_extensions as te @te.runtime class IntStackP(te.Protocol): _list: ty.List[int] def push(self, val: int) -> None: ... class IntStack: def __init__(self) -> None: self._list: ty.List[int] = list() def push(self, val: int) -> None: if not isinstance(val, int): raise TypeError('wrong pushued val type') self._list.append(val) class StrStack: def __init__(self) -> None: self._list: ty.List[str] = list() def push(self, val: str, weather: ty.Any=None) -> None: if not isinstance(val, str): raise TypeError('wrong pushued val type') self._list.append(val) def push_func(stack: IntStackP, value: int): if not isinstance(stack, IntStackP): raise TypeError('is not IntStackP') stack.push(value) a = IntStack() b = StrStack() c: ty.List[int] = list() push_func(a, 1) push_func(b, 1) # TypeError: wrong pushued val type push_func(c, 1) # TypeError: is not IntStackP 

рджреВрд╕рд░реА рдУрд░, MyPy, рдмрджрд▓реЗ рдореЗрдВ, рдЕрдзрд┐рдХ рдЪрд╛рд▓рд╛рдХреА рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЕрд╕рдВрдЧрддрд┐ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реИ:


 push_func(a, 1) push_func(b, 1) # Argument 1 to "push_func" has incompatible type "StrStack"; # expected "IntStackP" # Following member(s) of "StrStack" have conflicts: # _list: expected "List[int]", got "List[str]" # Expected: # def push(self, val: int) -> None # Got: # def push(self, val: str, weather: Optional[Any] = ...) -> None 

рд╕рдВрдЪрд╛рд▓рдХ рдЕрдзрд┐рднрд╛рд░


рдПрдХ рдмрд╣реБрдд рд╣реА рддрд╛рдЬрд╛ рд╡рд┐рд╖рдп, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдСрдкрд░реЗрдЯрд░реЛрдВ, рд╕рднреА рдордЬрд╝рд╛ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рд╢реНрди MyPy рдмрдЧ рдЯреНрд░реИрдХрд░ рдореЗрдВ рдмрд╛рд░-рдмрд╛рд░ рд╕рд╛рдордиреЗ рдЖрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд╢рдкрде рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдЖрдк рдЗрд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВ рд╕реНрдерд┐рддрд┐ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддрд╛ рд╣реВрдВ:


 class A: def __add__(self, other) -> int: return 3 def __iadd__(self, other) -> 'A': if isinstance(other, int): return NotImplemented return A() var = A() var += 3 # Inferred type is 'A', but runtime type is 'int'? 

рдпрджрд┐ рдорд┐рд╢реНрд░рд┐рдд рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╡рд┐рдзрд┐ NotImplemented , рддреЛ Python рдкрд╣рд▓реЗ __radd__ рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ __add__ , рдФрд░ voila рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред


рдлреЙрд░реНрдо рдХреЗ рдХрд┐рд╕реА рднреА рдЙрдкрд╡рд░реНрдЧ рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдпрд╣реА рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ:


 class A: def __add__(self, x : 'A') -> 'A': ... class B(A): @overload def __add__(self, x : 'A') -> 'A': ... @overload def __add__(self, x : 'B') -> 'B' : ... 

рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░, рдЪреЗрддрд╛рд╡рдирд┐рдпрд╛рдБ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЧрдИ рд╣реИрдВ, рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд╡реЗ рдЕрднреА рднреА рдареЗрд╕ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рд╕рд╛рдорд╛рдиреНрдп рдирд┐рд╖реНрдХрд░реНрд╖ рдРрд╕реЗ рдУрд╡рд░рд▓реЛрдб рдХреЛ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдЫреЛрдбрд╝ рджреЗрдирд╛ рд╣реИред

Source: https://habr.com/ru/post/hi437018/


All Articles