gopython
gorubyを使うとコードがとても短くなってゴルフが楽という話を聞いたので、Pythonでゴルフを楽にするにはどうすればいいかと考えてみる。徐々に書く。
In [3]: for i in range(10): ...: globals()["s%d"%i] = lambda x,i=i:globals().__setitem__("x%s"%i, x) ...: In [4]: s1(100) In [5]: x1 Out[5]: 100
とりあえず式の中でグローバル変数への代入を使えるようにしたけどどう考えても卑怯だ。
-
-
-
- -
-
-
class SetGlobals: def __getattr__(self, name): def func(value): globals().__setitem__(name, value) return value return func g = SetGlobals() print [g.x(2), x] # [2, 2]
これでようやく
[$x=2, $x]
が出来る言語と同じスタートラインに立った感じ。
-
-
-
- -
-
-
gorubyの短縮メソッド名の展開はこんな感じなのかな。
def find_item(namespace, name): """ >>> ns = "size range string stringstring x xs".split() >>> ns = dict(zip(ns, ns)) >>> find_item(ns, "x") 'x' >>> find_item(ns, "r") 'range' >>> find_item(ns, "si") 'size' >>> find_item(ns, "ss") 'stringstring' """ if name in namespace: return namespace[name] candidate = [k for k in namespace if k.startswith(name)] if len(candidate) == 1: return candidate[0] # zero or more than one exact matches for can in namespace: start = 0 for c in name: start = can.find(c, start) + 1 if start == 0: break else: return can raise RuntimeError(candidate)
-
-
-
- -
-
-
っていうかとにかく短く書けるようにするためには、とある魔力の源(マナ)みたいなオブジェクトがあるべきだと思うんだよ。
でもって、そのマナから導きだしたオブジェクトはすべて魔力を帯びるようにするべきだと思うんだよ。
class Mana: def __call__(self, v): "add magical power" if isinstance(v, str): return MagicalString(v) if isinstance(v, int): return MagicalInteger(v) M = Mana() class MagicalObject: def __init__(self, v): self.value = v class MagicalString(MagicalObject): def __add__(self, v): if isinstance(v, MagicalObject): v = v.value if isinstance(v, int): return self.value + str(v) return self.value + v class MagicalInteger(MagicalObject): def __add__(self, v): if isinstance(v, MagicalObject): v = v.value if isinstance(v, str): return self.value + int(v) return self.value + v i = M(100) s = M("100") print i + s #=> 200 print s + i #=> 100100
これでようやく "foo" + 100とかが出来るようになった。
-
-
-
- -
-
-
MagicalListは+で破壊的に追加をするようにした。なぜならコピーをとるのは[:]の3バイトでいいから。あとハッシュのキーになれるようにした。
class MagicalList(MagicalObject): """ >>> xs = MagicalList(0, 1, 2) >>> xs.value [0, 1, 2] >>> (xs + 3).value [0, 1, 2, 3] >>> d = {} >>> d[xs] = 0 >>> d[MagicalList(0,1,2,3)] 0 """ def __init__(self, *value): if len(value) == 1: self.value = list(value[0]) self.value = list(value) def join(self, x): return M(x.join(self.value)) def __hash__(self): return hash(tuple(self.value)) def __eq__(self, v): if isinstance(v, MagicalObject): v = v.value return self.value == v def __add__(self, value): """add destructively""" if isinstance(value, list) or isinstance(value, tuple): self.value.extend(value) else: self.value.append(value) return self
完成にはほど遠いが飽きてきた。全体のコードを見たい人がたくさんいたらCodeReposに入れる。見たい人ははてなスターでも押してみて。