2017-04-04 60 views
7

Czy istnieje jakaś różnica między używaniem odwrotnych operatorów związków lub skrzyżowań w zestawach w Pythonie?Praktyczne użycie operatorów odwróconych w Pythonie

na przykład

s & z odpowiada s.__and__(z)

z & s odpowiada s.__rand__(z)

Jeśli te mają powrócić to samo, dlaczego mają odwrócone operator w pierwszej kolejności? Czy czegoś brakuje?

+0

Dzieje się tak, gdy obiekt po lewej stronie nie implementuje metody "__and__". –

Odpowiedz

0

__rand__ jest wywoływana tylko wtedy, gdy lewy operand nie obsługuje odpowiedniej operacji, a operandy są różnych typów.

Wyobrażam sobie, że s.__rand__(z) zadzwoniłaby pod numer z.__and__(s).

+0

Ponieważ operacja jest nieprawidłowa, z wyjątkiem dwóch zestawów, drugi argument ma poprawną metodę lub wystąpił błąd, a metoda rand nie musi być tą, która ją tworzy. – zondo

3

set i frozenset śledzić protokół numer i oni don't define the reversed operations explicitly ale dostać te „za darmo”, ponieważ implement the normal methods (like __and__).

Jednak operacje odwrotne są szczególnie przydatne w przypadku podklas, ponieważ jeśli right operand is a subclass of the left operand the reversed operation is attempted first. Ale w przypadku zwykłych set s i frozenset s nie ma to znaczenia, ponieważ nie dziedziczą one od siebie nawzajem.

Te odwrócone operacje są również używane, jeśli pierwszy operand zwraca NotImplemented w swoim numerze __add__. Ale znowu nie jest to użyteczne dla set i frozenset, ponieważ pozwalają one tylko operacjom z innymi set -alekami i co najmniej set i frozenset nie zwracają NotImplemented, gdy inny operand jest inny set.

Również z & s nie odpowiada s.__rand__(z), chyba że s jest podklasą z. W przeciwnym razie zostanie podjęta próba przed s.__rand__(z).

Tak więc wątpię, aby były przypadki użycia dla odwróconego związku i skrzyżowania, ale powinno to wyjaśniać "dlaczego te metody istnieją".

+0

Czy mówisz, że jeśli tworzę klasy niestandardowe, które dziedziczą po 'set' lub' frozenset', a te klasy mają różne metody '__and__', to trzeba uważać na kolejność i jakie są również metody' __rand__'? – MadPhysicist

+1

Rzeczywiście z 'set' i' frozenset' musisz być ostrożny przy zamówieniu, kiedy podklasujesz i próbujesz działać z drugim. Jeśli twoja podklasa 'set' i implementuje' __and__' i '__rand__' twoje metody podklas zostaną wywołane jako pierwsze, gdy spróbujesz zrobić' set() i podklasę() '(=>' podklasa .__ rand__' jest wywoływana jako pierwsza) lub ' podklasa() i zestaw() '(=>' podklasa .__ i__' jest wywoływana jako pierwsza). Ale jeśli spróbujesz użyć tej podklasy za pomocą 'frozenset', musisz uważać na kolejność:' frozenset() i subklasa() 'będą najpierw wywoływać' frozenset .__ and__'! – MSeifert