Archive for September, 2011


除了java等少数语言,大部分现代语言都支持运算符重载,

比如说在C++中,我们既可以这样写

a = 1 + 1; //a =2

也可以这样把一个运算符改变意义重载成例如:

a = “abc” + “def”; // a = “abcdef”

在python中,传统的可重载运算符包括,

+, -, *,**, /, %, []等等,分别对应的__add__等成员方法

今天我想到了个问题,能不呢自己定义一些比较酷的方法,实用python原来没有的运算符呢?

例如,我想求一个10的阶乘,直接用 10$ = 1*2*3*4*5*6*7*8*9*10

在例如,我想求3,8两个数的最大公约束gcd,直接用 3 @g@ 8 = 1

---------------

google了一下,发现很遗憾的是python并不提供这么BT的运算符自定义功能,但是仅仅是python本身不提供,并不代表hack们做不到,于是这个hack就被提出了了:

我们假设某一个运算,称它为X,有一个对象支持这种运算,我们称为y。

首先,这个hack最重要的一个思想是,python的运算符重载和其他语言不一样的地方在于,不仅提供重载 ? X y这种运算符在对象左边的重载,还同时支持 y X ?这种在右边的重载。

于是开始了!

---------------

我们的任务:重载一个求gcd的运算。达到这样的各式: x gcd y = gcd(x,y)

上代码:

class Infix:

def __init__(self,function):

self.function = function

def __ror__(self,other):

return Infix(lambda x, self=self, other=other: self.function(other,x))

def __or__(self,other):

return self.function(other)

def __call__(self,value1,value2):

return self.function(value1,value2)

———————–

在这里我们定义了一个特殊的类Infix来进行运算符的处理,接下来我们看看怎么用:

首先,写一个gcd函数:

>>>gcd = lambda x,y: gcd(y,x) if x>>g = Infix(gcd)

>>>print 104 |g| 78

26

得到了输出!

——————

于是瞬间我就觉得这太酷了简直碉堡了啊有木有啊!

当然,著名的pipe包也实用了类似的原理,实现了流式程序,

但是这么活用这个原理的这个hack恐怕是第一个了吧。。。

同样道理,也可以自己定制其他的各式的运算符,例如

比较萌的*_*, ^_^, (T_T),

传统一点的++, --神马的。。。

--------------

追加一句,其实ruby也是有类似的功能的

Advertisements

作为热身,用2011年6月的比赛题目写了一下。

最近准备开始把自己写的代码以及问题的分析传上来。

python为主吧。

Mac摸索中。

先后安装了:

port

byobu

zsh

emacs vim

 

—————–

正在配置:

robocup simulator

需要: bison/flex, boost, qt4, zlib