class BitShiftFunc: def __init__(self, f): self.f = f def __lshift__(self, rhs): return self.f(rhs) def __getattr__(self, f): @BitShiftFunc def composed(x): return self.f(globals()[f](x)) return composed def __mul__(self, times): @BitShiftFunc def runner(x): start = x for _ in range(times): start = self.f(start) return start return runner def __call__(self, *args, **kwds): return self.f(*args, **kwds) @BitShiftFunc def square(x): return x * x @BitShiftFunc def inc(x): return x + 1 def cube(x): return x ** 3 def main(): print(BitShiftFunc(cube) << 3) # 27 print(BitShiftFunc(len) << 'Hello') # 5 print(square(2)) # 4 print(square << 2) # 4 print(square.inc << 2) # 9 print(inc.square << 2) # 5 print(inc.inc.square.inc << 2) # 11 print((inc.inc.square.inc * 2) << 2) # 146 print((inc * 4) << 2) # 6 if __name__ == '__main__': main()