SlideShare a Scribd company logo
1 of 40
Getting Rich With Comparison Methods
Matt Story (@mscottstory) // PyGotham – August, 2014
eng.handshake.com
@handshakeeng
$2.50
The most certain of all basic
principles is that contradictory
propositions are not true
simultaneously.
~ Aristotle -- Metaphisics
>>> from philosopher import Philosopher
>>> aristotle = Philosopher.load(“Aristotle”)
>>> aristotle == Philosopher.load(“Aristotle”)
True
>>> from philosopher import Philosopher
>>> aristotle = Philosopher.load(“Aristotle”)
>>> aristotle == Philosopher.load(“Aristotle”)
True
>>> aristotle != Philosopher.load(“Aristotle”)
True
How Am I Not Myself?
class Philosopher(JSONStore):
'''JSONStore provides `load` and `save`'''
store = './lyceum'
dump_these = ('name', ‘rep’, 'works’)
def __init__(self, name, rep=5, works=tuple()):
self.name = name
self.rep = rep
self.works = list(works)
super(Philosopher,
self).__init__(name.lower())
def __eq__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, ‘id’):
return self.id == other.id
return NotImplemented
class Philosopher(JSONStore):
'''JSONStore provides `load` and `save`'''
store = './lyceum'
dump_these = ('name', ‘rep’, 'works’)
def __init__(self, name, rep=5, works=tuple()):
self.name = name
self.rep = rep
self.works = list(works)
super(Philosopher,
self).__init__(name.lower())
def __eq__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, ‘id’):
return self.id == other.id
return NotImplemented
There are no implied relationships among the
comparison operators. The truth of x == y does
not imply that x != y is false. Accordingly, when
defining __eq__(), one should also define
__ne__() so that the operators will behave as
expected.
5 Minutes Later …
class Philosopher(JSONStore):
# ... snip
def __eq__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, ‘id’):
return self.id == other.id
return NotImplemented
def __ne__(self, other):
is_eq = self.__eq__(other)
if is_eq is NotImplemented:
return is_eq
return not is_eq
class Philosopher(JSONStore):
# ... snip
def __eq__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, ‘id’):
return self.id == other.id
return NotImplemented
def __ne__(self, other):
is_eq = self.__eq__(other)
if is_eq is NotImplemented:
return is_eq
return not is_eq
>>> aristotle == Philosopher.load(“Aristotle”)
True
>>> aristotle != Philosopher.load(“Aristotle”)
False
Aristotle
KANT
class Philosopher(JSONStore):
# ... Snip
def __gt__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, 'rep'):
return self.rep > other.rep
return NotImplemented
>>> aristotle = Philosopher.load(‘Aristotle’)
>>> kant = Philosopher.load(‘Kant’)
>>> print aristotle.rep
10
>>> print kant.rep
8
>>> aristotle > kant
True
>>> aristotle = Philosopher.load(‘Aristotle’)
>>> kant = Philosopher.load(‘Kant’)
>>> print aristotle.rep
10
>>> print kant.rep
8
>>> aristotle > kant
True
>>> kant < aristotle
True
5 Seconds Later …
There are no swapped-argument versions of
these methods (to be used when the left
argument does not support the operation but
the right argument does); rather, __lt__() and
__gt__() are each other’s reflection, __le__()
and __ge__() are each other’s reflection, and
__eq__() and __ne__() are their own reflection.
class Philosopher(JSONStore):
# ... Snip
def __gt__(self, other):
print ’{}: called __gt__’.format(self.name)
if isinstance(self, other.__class__) 
and hasattr(other, 'rep'):
return self.rep > other.rep
return NotImplemented
>>> aristotle > kant
Aristotle: called __gt__
True
>>> kant < aristotle
Aristotle: called __gt__
True
NotImplemented
This type has a single value. There is a single
object with this value … Rich comparison
methods may return this value if they do not
implement the operation for the operands
provided. (The interpreter will then try the
reflected operation, or some other fallback,
depending on the operator.)
>>> "abc".__lt__(0)
NotImplemented
Right-Side
Reflection Returns
NotImplemented
Left-Side Method
Is Defined
Yes
No
Left-Side Method
Returns
NotImplemented
Yes
No
Return
Right-Side
Reflection Is
Defined
Return
Yes
No
Return Default (is)
No
Aristotle
Foucault
class PostModernist(Philosopher):
def __lt__(self, other):
if isinstance(self, other.__class__):
# with panopticon authority
return False
return NotImplemented
>>> from philosopher import PostModernist
>>> foucault = PostModernist.load('Foucault')
>>> foucault.rep
6
>>> aristotle.rep
10
>>> aristotle > foucault
>>> from philosopher import PostModernist
>>> foucault = PostModernist.load('Foucault')
>>> foucault.rep
6
>>> aristotle.rep
10
>>> aristotle > foucault
False
class PostModernist(Philosopher):
def __lt__(self, other):
print ’{}: __lt__ called'.format(self.name)
if isinstance(self, other.__class__):
return False
return NotImplemented
>>> aristotle > foucault
Foucault: called __lt__
False
import operator
assert operator.lt(kant, aristotle)
assert operator.gt(aristotle, kant)
assert operator.eq(kant, kant)
assert operator.eq(aristotle, kant)
__eq__
__ne__
__lt__
__le__
__gt__
__ge__
Lots of methods, means lots of redundant code
@functools.total_ordering
class Philosopher(JSONStore):
# ... snip
def __eq__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, ‘id’):
return self.id == other.id
return NotImplemented
def __gt__(self, other):
if isinstance(self, other.__class__) 
and hasattr(other, 'rep'):
return self.rep > other.rep
return NotImplemented
def __ne__(self, other):
# snip ...
class X(object):
def __eq__(self, other):
return lambda x: x == other
def __ne__(self, other):
return lambda x: x != other
def __lt__(self, other):
return lambda x: x < other
def __le__(self, other):
return lambda x: x <= other
def __gt__(self, other):
return lambda x: x > other
def __ge__(self, other):
return lambda x: x >= other
x = X()
>>> filter(x == 2, range(5))
[2]
>>> filter(x > 1, range(5))
[2, 3, 4]
Thanks
@mscottstory

More Related Content

Similar to Getting Rich With Comparison Methods

Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and ScalaFolding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and ScalaPhilip Schwarz
 
Greach 2015 AST – Groovy Transformers: More than meets the eye!
Greach 2015   AST – Groovy Transformers: More than meets the eye!Greach 2015   AST – Groovy Transformers: More than meets the eye!
Greach 2015 AST – Groovy Transformers: More than meets the eye!Iván López Martín
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
 
Chap 3php array part 3
Chap 3php array part 3Chap 3php array part 3
Chap 3php array part 3monikadeshmane
 
Python's magic methods
Python's magic methodsPython's magic methods
Python's magic methodsReuven Lerner
 
The groovy puzzlers (as Presented at Gr8Conf US 2014)
The groovy puzzlers (as Presented at Gr8Conf US 2014)The groovy puzzlers (as Presented at Gr8Conf US 2014)
The groovy puzzlers (as Presented at Gr8Conf US 2014)GroovyPuzzlers
 

Similar to Getting Rich With Comparison Methods (12)

Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
E6
E6E6
E6
 
Recursion part 2
Recursion part 2Recursion part 2
Recursion part 2
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and ScalaFolding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala
 
Greach 2015 AST – Groovy Transformers: More than meets the eye!
Greach 2015   AST – Groovy Transformers: More than meets the eye!Greach 2015   AST – Groovy Transformers: More than meets the eye!
Greach 2015 AST – Groovy Transformers: More than meets the eye!
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
 
Chap 3php array part 3
Chap 3php array part 3Chap 3php array part 3
Chap 3php array part 3
 
Python's magic methods
Python's magic methodsPython's magic methods
Python's magic methods
 
The groovy puzzlers (as Presented at Gr8Conf US 2014)
The groovy puzzlers (as Presented at Gr8Conf US 2014)The groovy puzzlers (as Presented at Gr8Conf US 2014)
The groovy puzzlers (as Presented at Gr8Conf US 2014)
 

Recently uploaded

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Recently uploaded (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Getting Rich With Comparison Methods

  • 1. Getting Rich With Comparison Methods Matt Story (@mscottstory) // PyGotham – August, 2014
  • 4. The most certain of all basic principles is that contradictory propositions are not true simultaneously. ~ Aristotle -- Metaphisics
  • 5. >>> from philosopher import Philosopher >>> aristotle = Philosopher.load(“Aristotle”) >>> aristotle == Philosopher.load(“Aristotle”) True
  • 6. >>> from philosopher import Philosopher >>> aristotle = Philosopher.load(“Aristotle”) >>> aristotle == Philosopher.load(“Aristotle”) True >>> aristotle != Philosopher.load(“Aristotle”) True
  • 7. How Am I Not Myself?
  • 8. class Philosopher(JSONStore): '''JSONStore provides `load` and `save`''' store = './lyceum' dump_these = ('name', ‘rep’, 'works’) def __init__(self, name, rep=5, works=tuple()): self.name = name self.rep = rep self.works = list(works) super(Philosopher, self).__init__(name.lower()) def __eq__(self, other): if isinstance(self, other.__class__) and hasattr(other, ‘id’): return self.id == other.id return NotImplemented
  • 9. class Philosopher(JSONStore): '''JSONStore provides `load` and `save`''' store = './lyceum' dump_these = ('name', ‘rep’, 'works’) def __init__(self, name, rep=5, works=tuple()): self.name = name self.rep = rep self.works = list(works) super(Philosopher, self).__init__(name.lower()) def __eq__(self, other): if isinstance(self, other.__class__) and hasattr(other, ‘id’): return self.id == other.id return NotImplemented
  • 10.
  • 11. There are no implied relationships among the comparison operators. The truth of x == y does not imply that x != y is false. Accordingly, when defining __eq__(), one should also define __ne__() so that the operators will behave as expected. 5 Minutes Later …
  • 12. class Philosopher(JSONStore): # ... snip def __eq__(self, other): if isinstance(self, other.__class__) and hasattr(other, ‘id’): return self.id == other.id return NotImplemented def __ne__(self, other): is_eq = self.__eq__(other) if is_eq is NotImplemented: return is_eq return not is_eq
  • 13. class Philosopher(JSONStore): # ... snip def __eq__(self, other): if isinstance(self, other.__class__) and hasattr(other, ‘id’): return self.id == other.id return NotImplemented def __ne__(self, other): is_eq = self.__eq__(other) if is_eq is NotImplemented: return is_eq return not is_eq
  • 14. >>> aristotle == Philosopher.load(“Aristotle”) True >>> aristotle != Philosopher.load(“Aristotle”) False
  • 16. class Philosopher(JSONStore): # ... Snip def __gt__(self, other): if isinstance(self, other.__class__) and hasattr(other, 'rep'): return self.rep > other.rep return NotImplemented
  • 17. >>> aristotle = Philosopher.load(‘Aristotle’) >>> kant = Philosopher.load(‘Kant’) >>> print aristotle.rep 10 >>> print kant.rep 8 >>> aristotle > kant True
  • 18. >>> aristotle = Philosopher.load(‘Aristotle’) >>> kant = Philosopher.load(‘Kant’) >>> print aristotle.rep 10 >>> print kant.rep 8 >>> aristotle > kant True >>> kant < aristotle True
  • 19.
  • 20. 5 Seconds Later … There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, __lt__() and __gt__() are each other’s reflection, __le__() and __ge__() are each other’s reflection, and __eq__() and __ne__() are their own reflection.
  • 21. class Philosopher(JSONStore): # ... Snip def __gt__(self, other): print ’{}: called __gt__’.format(self.name) if isinstance(self, other.__class__) and hasattr(other, 'rep'): return self.rep > other.rep return NotImplemented
  • 22. >>> aristotle > kant Aristotle: called __gt__ True >>> kant < aristotle Aristotle: called __gt__ True
  • 23. NotImplemented This type has a single value. There is a single object with this value … Rich comparison methods may return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.)
  • 25. Right-Side Reflection Returns NotImplemented Left-Side Method Is Defined Yes No Left-Side Method Returns NotImplemented Yes No Return Right-Side Reflection Is Defined Return Yes No Return Default (is) No
  • 27. class PostModernist(Philosopher): def __lt__(self, other): if isinstance(self, other.__class__): # with panopticon authority return False return NotImplemented
  • 28. >>> from philosopher import PostModernist >>> foucault = PostModernist.load('Foucault') >>> foucault.rep 6 >>> aristotle.rep 10 >>> aristotle > foucault
  • 29. >>> from philosopher import PostModernist >>> foucault = PostModernist.load('Foucault') >>> foucault.rep 6 >>> aristotle.rep 10 >>> aristotle > foucault False
  • 30. class PostModernist(Philosopher): def __lt__(self, other): print ’{}: __lt__ called'.format(self.name) if isinstance(self, other.__class__): return False return NotImplemented
  • 31. >>> aristotle > foucault Foucault: called __lt__ False
  • 32.
  • 33. import operator assert operator.lt(kant, aristotle) assert operator.gt(aristotle, kant) assert operator.eq(kant, kant) assert operator.eq(aristotle, kant)
  • 35. @functools.total_ordering class Philosopher(JSONStore): # ... snip def __eq__(self, other): if isinstance(self, other.__class__) and hasattr(other, ‘id’): return self.id == other.id return NotImplemented def __gt__(self, other): if isinstance(self, other.__class__) and hasattr(other, 'rep'): return self.rep > other.rep return NotImplemented def __ne__(self, other): # snip ...
  • 36.
  • 37. class X(object): def __eq__(self, other): return lambda x: x == other def __ne__(self, other): return lambda x: x != other def __lt__(self, other): return lambda x: x < other def __le__(self, other): return lambda x: x <= other def __gt__(self, other): return lambda x: x > other def __ge__(self, other): return lambda x: x >= other x = X()
  • 38. >>> filter(x == 2, range(5)) [2] >>> filter(x > 1, range(5)) [2, 3, 4]
  • 39.