Представления словаря «подобны множеству», но в отличие от set
, они не имеют именованных методов (типа гибких) (например, .union
, как в вашем примере), они просто имеют перегрузки операторов, которые остаются типамигибкие (так как названные методы не существуют).
Будучи гибкими по типу, они работают с any итерируемыми в качестве другого операнда, а dict
s являются итерируемыми их ключами (list({'a': 1, 'b': 2})
равно ['a', 'b']
), поэтому значения игнорируются в операции просмотра.Дело не в том, что dict
здесь специально приняты, они просто обрабатываются как любые другие итерируемые (вы можете |
представление словаря с генератором dict
, list
, tuple
, range
или подобный файлу объект, и все они работали бы, предполагая хешируемое содержимое, и в результате получали бы set
).
Не так уж плохо для представлений быть более гибкими, потому что они ненамереваясь сохранить свой собственный тип после операции, ожидается, что они будут выдавать set
выходных данных.Операторы set
вне места более строги, потому что они не хотят неявно отдавать приоритет типу левой или правой стороны при определении типа вывода (они не хотят set OP nonset
оставить сомнение относительно того, имеет ли результат тип set
или nonset
, и они не хотят, чтобы nonset OP set
вел себя по-другому).Поскольку представления словаря в любом случае не сохраняют типы, они решили пойти на более либеральный дизайн для своих перегрузок операторов;результат view OP nonview
и nonview OP view
является согласованным, и это всегда set
.
Документированная причина поддержки этих конкретных операций - для соответствия функциям collections.abc.Set
:
Для множественных представлений доступны все операции, определенные для абстрактного базового класса collections.abc.Set
(например, ==
, <
или^
).
и по некоторым причинам collections.abc.Set
не требует ни одного из названных методов (кроме isdisjoint
) , только перегрузки оператора.
Примечание: я не согласен с этим (я бы предпочел, чтобы представления работали только с их операторами, работающими с другими представлениями и с set
/ frozenset
, и чтобы представления имели именованные методы какхорошо для согласованности), но уже слишком поздно что-либо менять, так что это так.
Что касается методов set
с гибкой типизацией, то это был скорее преднамеренный выбор.Операторы не производят сильное впечатление, что один из операндов более важен, в то время как методы обязательно делают (вещь, которую вы вызвали, очевидно, более важна, чем аргументы).Таким образом, методы принимают произвольные итерации (и фактически могут принимать более одной итерации, как в {1, 2, 3}.union(range(5), range(10, 15))
) и возвращают тип объекта, для которого они были вызваны, в то время как операторы настаивают на том, что типы соглашаются избегать неожиданностей.