Skip to content

Instantly share code, notes, and snippets.

@tamsanh
Created April 30, 2018 23:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamsanh/19abf12ef97ea1c86f1ea703c80db5b3 to your computer and use it in GitHub Desktop.
Save tamsanh/19abf12ef97ea1c86f1ea703c80db5b3 to your computer and use it in GitHub Desktop.
Python __rshift__ __lshift __rrshift__ __rlshift__ Examples and Order of Operations
# Setup Classes for the Example
class Shifter:
def __init__(self, label):
self.label = label
def __str__(self):
return str(self.label)
def __rshift__(self, other):
print("#%s.__rshift__(%s)" % (self, other))
return self
def __lshift__(self, other):
print("#%s.__lshift__(%s)" % (self, other))
return self
def __rrshift__(self, other):
print("%s.__rrshift__(%s)" % (self, other))
return self
def __rlshift__(self, other):
print("#%s.__rlshift__(%s)" % (self, other))
return self
class NotShifter:
def __init__(self, label):
self.label = label
def __str__(self):
return str(self.label)
A = Shifter("A")
B = Shifter("B")
C = Shifter("C")
Z = NotShifter("Z")
## Example Outputs
A >> B >> C
# A.__rshift__(B)
# A.__rshift__(C)
(A >> B) >> C
# A.__rshift__(B)
# A.__rshift__(C)
A >> (B >> C)
# B.__rshift__(C)
# A.__rshift__(B)
A >> B << C
# A.__rshift__(B)
# A.__lshift__(C)
(A >> B) << C
# A.__rshift__(B)
# A.__lshift__(C)
A >> (B << C)
# B.__lshift__(C)
# A.__rshift__(B)
A << B >> C
# A.__lshift__(B)
# A.__rshift__(C)
(A << B) >> C
# A.__lshift__(B)
# A.__rshift__(C)
A << (B >> C)
# B.__rshift__(C)
# A.__lshift__(B)
A << B << C
# A.__lshift__(B)
# A.__lshift__(C)
(A << B) << C
# A.__lshift__(B)
# A.__lshift__(C)
A << (B << C)
# B.__lshift__(C)
# A.__lshift__(B)
Z >> B >> C
# B.__rrshift__(Z)
# B.__rshift__(C)
(Z >> B) >> C
# B.__rrshift__(Z)
# B.__rshift__(C)
Z >> (B >> C)
# B.__rshift__(C)
# B.__rrshift__(Z)
Z >> B << C
# B.__rrshift__(Z)
# B.__lshift__(C)
(Z >> B) << C
# B.__rrshift__(Z)
# B.__lshift__(C)
Z >> (B << C)
# B.__lshift__(C)
# B.__rrshift__(Z)
Z << B >> C
# B.__rlshift__(Z)
# B.__rshift__(C)
(Z << B) >> C
# B.__rlshift__(Z)
# B.__rshift__(C)
Z << (B >> C)
# B.__rshift__(C)
# B.__rlshift__(Z)
Z << B << C
# B.__rlshift__(Z)
# B.__lshift__(C)
(Z << B) << C
# B.__rlshift__(Z)
# B.__lshift__(C)
Z << (B << C)
# B.__lshift__(C)
# B.__rlshift__(Z)
A >> Z >> C
# A.__rshift__(Z)
# A.__rshift__(C)
(A >> Z) >> C
# A.__rshift__(Z)
# A.__rshift__(C)
A >> (Z >> C)
# C.__rrshift__(Z)
# A.__rshift__(C)
A >> Z << C
# A.__rshift__(Z)
# A.__lshift__(C)
(A >> Z) << C
# A.__rshift__(Z)
# A.__lshift__(C)
A >> (Z << C)
# C.__rlshift__(Z)
# A.__rshift__(C)
A << Z >> C
# A.__lshift__(Z)
# A.__rshift__(C)
(A << Z) >> C
# A.__lshift__(Z)
# A.__rshift__(C)
A << (Z >> C)
# C.__rrshift__(Z)
# A.__lshift__(C)
A << Z << C
# A.__lshift__(Z)
# A.__lshift__(C)
(A << Z) << C
# A.__lshift__(Z)
# A.__lshift__(C)
A << (Z << C)
# C.__rlshift__(Z)
# A.__lshift__(C)
A >> B >> Z
# A.__rshift__(B)
# A.__rshift__(Z)
(A >> B) >> Z
# A.__rshift__(B)
# A.__rshift__(Z)
A >> (B >> Z)
# B.__rshift__(Z)
# A.__rshift__(B)
A >> B << Z
# A.__rshift__(B)
# A.__lshift__(Z)
(A >> B) << Z
# A.__rshift__(B)
# A.__lshift__(Z)
A >> (B << Z)
# B.__lshift__(Z)
# A.__rshift__(B)
A << B >> Z
# A.__lshift__(B)
# A.__rshift__(Z)
(A << B) >> Z
# A.__lshift__(B)
# A.__rshift__(Z)
A << (B >> Z)
# B.__rshift__(Z)
# A.__lshift__(B)
A << B << Z
# A.__lshift__(B)
# A.__lshift__(Z)
(A << B) << Z
# A.__lshift__(B)
# A.__lshift__(Z)
A << (B << Z)
# B.__lshift__(Z)
# A.__lshift__(B)
## Summary
# 1. Order starts from the left to the right, no matter if left or right shifters.
# Output of the first combination will be used as the left operator of the next operation.
# 2. Parenthesis change the order of operations as one would expect.
# 2. __rshift__ and __lshift__ operations are only called on classes that implement it.
# If one of the classes does not implement it, then the __rrshift__ or __rlshift__ operations are called.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment