В Python Type[Union[A, B, C]]
— это то же самое, что Union[Type[A], Type[B], Type[C]]
?
Я думаю, что они эквивалентны, и переводчик, похоже, с этим согласен.
Чтобы внести ясность: мне нужен союз типов A, B или C, а не объединение экземпляров A, B или C. Первый вариант короче и, ИМХО, более читабелен.
Другими словами, учитывая эти определения:
class A:
pass
class B:
pass
class C:
pass
def foo(my_class: Type[Union[A, B, C]]):
pass
Я ожидаю, что это использование будет правильным:
foo(A) # pass the class A itself
Но не этот:
foo(A()) # pass an instance of A
Обратите внимание, что ответ «да» на этот вопрос не обобщает: хотя тип является дистрибутивным, а не объединенным, например list[A | B]
это не то же самое, что list[A] | list[B]
Я знаю, но это хорошее дополнение на случай, если кто-то задаст этот вопрос в поисках чего-то подобного. Спасибо!
Они одинаковые. Вы можете использовать reveal_type
и проверить.
class A: ...
class B: ...
class C: ...
def something(a: type[A | B | C]) -> None:
reveal_type(a)
def something_else(b: type[A] | type[B]| type[C]) -> None:
reveal_type(b)
mypy main.py
main.py:6: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
main.py:9: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
pyright main.py
main.py:6:17 - information: Type of "a" is "type[A] | type[B] | type[C]"
main.py:9:17 - information: Type of "b" is "type[A] | type[B] | type[C]"
Редактировать:
Старый синтаксис
from typing import Union, Type
class A: ...
class B: ...
class C: ...
def something(a: type[A | B | C]) -> None:
reveal_type(a)
def something_else(b: type[A] | type[B]| type[C]) -> None:
reveal_type(b)
def old_something(c: Type[Union[A, B, C]]) -> None:
reveal_type(c)
def old_something_else(d: Union[Type[A], Type[B], Type[C]]) -> None:
reveal_type(d)
mypy main.py
main.py:7: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
main.py:10: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
main.py:13: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
main.py:16: note: Revealed type is "Union[type[main.A], type[main.B], type[main.C]]"
pyright main.py
main.py:7:17 - information: Type of "a" is "type[A] | type[B] | type[C]"
main.py:10:17 - information: Type of "b" is "type[A] | type[B] | type[C]"
main.py:13:17 - information: Type of "c" is "type[A] | type[B] | type[C]"
main.py:16:17 - information: Type of "d" is "type[A] | type[B] | type[C]"
Кроме того, мне интересно, какой из них более читабелен для людей, кроме меня.
@noamtm Я, вероятно, предпочел бы тот, который я использовал для something
, поскольку он короче, но если вы действительно хотите улучшить читабельность, я бы предпочел добавить псевдоним типа.
Для этой задачи я остановился на версии Python, которая не поддерживает новый синтаксис Union, поэтому мой вариант больше похож на ваш old_something
.
В этом конкретном контексте я вынужден использовать версию Python, которая не поддерживает новый синтаксис объединения
A | B | C
.