几个 Python 语法糖的实现

来源:互联网 发布:淘宝卖家如何改差评 编辑:程序博客网 时间:2024/05/18 00:31

受这位小哥(https://github.com/czheo/syntax_sugar_python)的启发,我照着它的 Usage 实现了一部分语法糖。

1. compose

实现compose函数,满足如下操作:

f = lambda x: x**2 + 1g = lambda x: 2*x - 1h = lambda x: -2 * x**3 + 3fgh = compose(f, g, h)# equivalent to `f(g(h(n)))`print fgh(5) # 245026

我们可以让compose返回一个函数,这个函数倒序遍历compose中的参数,并对输入参数调用该参数。

def compose(*args):    def retFunc(x):        i = len(args) - 1        while i >= 0:            func = args[i]            assert(func.__call__)            x = func(x)            i -= 1        return x    return retFunc

2. composable

实现composable函数,满足如下操作:

@composabledef add2(x):    return x + 2@composabledef mul3(x):    return x * 3@composabledef pow2(x):    return x ** 2fn = add2 * mul3 * pow2# equivalent to `add2(mul3(pow2(n)))`print fn(5) # 77

composable函数接受一个函数,返回一个封装后的东西让其可以通过*来复合。那我们就创建一个类来封装这些东西好了。

class Composable(object):    def __init__(self, *args):        object.__init__(self)        for f in args:            assert(f.__call__)        self.func = args    def __call__(self, x):        i = len(self.func) - 1        while i >= 0:            func = self.func[i]            assert(func.__call__)            x = func(x)            i -= 1        return x    def __mul__(self, rv):        assert(isinstance(rv, Composable))        return Composable(*(self.func + rv.func))composable = Composable

3.infix

实现infix,满足:

@infixdef plus(a, b):    return a + bprint 1 /plus/ 2# equivalent to `plus(1, 2)`print 1 /of/ int# equivalent to `isinstance(1, int)`print 1 /to/ 10# equivalent to `range(1, 11)`

我们可以看到,infix函数接受一个函数,并把这个函数变成中缀。of可以看做isinstance的中缀,to可以看做range的中缀(需要微调)。

我们先把后两个定义出来:

of = infix(isinstance)to = infix(lambda x, y: range(x, y + 1))

然后实现infix

class Infix(object):    def __init__(self, f):        object.__init__(self)        assert(f.__call__)        self.func = f        self.set = False    def __rdiv__(self, i):        assert(not self.set)        r = Infix(self.func)        r.set = True        r.left = i        return r    def __div__(self, t):        assert(self.set)        r = self.func(self.left, t)        self.set = False        return r    def __call__(self, *args, **kwargs):        return self.f(*args, **kwargs)infix = Infix
0 0
原创粉丝点击