Pythonで++i
この間、Pythonで変数のインクリメントないよね、って話がでた。こんなのだ。
i = 99 ++i print i
ちなみに、Pythonでも ++i や --i と書くことはできる。書くことはできるが、Pythonでは ++ や -- はインクリメント/デクリメント演算子ではなく、単項の + や - を二つ続けて書いているだけで、こう書いたのと同じ結果になるだけだ。
++i == +(+(i)) --i == -(-(i))
だが、ここで重要なのは、この式はコンパイルエラーにはならないという事実だ。コンパイルエラーにならないということは、すなわち抽象構文木(AST)を作れるということだ。そしてASTを作れるということは、みんな大好きastモジュールで好き勝手できるということなのである。
import ast class InclTransformer(ast.NodeTransformer): def visit_Expr(self, node): if isinstance(node.value, ast.UnaryOp): if isinstance(node.value.op, ast.UAdd): if isinstance(node.value.operand, ast.UnaryOp): if isinstance(node.value.operand.op, ast.UAdd): num = ast.copy_location(ast.Num(n=1), node) n = ast.AugAssign( target=node.value.operand.operand, op=ast.Add(), value=num) return ast.copy_location(n, node) return node s = """ def inc(i): ++i return i """ m = ast.parse(s, "filename", "exec") exec compile(InclTransformer().visit(m), "filename", "exec") in globals() print inc(99)