py3kのprintが好きじゃないわけ

print は pythonic ではないと認識されていて、 py3k では関数になります。

print("foo", 3, "baz", end='', sep=',') # foo,3,baz

http://d.hatena.ne.jp/methane/20090602/1243914597

そうそう、それ。名前付き引数を使ってるところ。改行するかしないかは一意に決まっていることがほとんどなんだから、7文字以上も余計に書くことがわずらわしい。sepパラメータは許容範囲。
こう考える理由を考えてみたけど、好みの問題とデフォルトの問題と用途の問題が複雑に絡んだ結果だと思う。

  • そもそも名前付き引数があまり好きじゃない。特にこのprintにおいては。付加的な修飾だからというのは理解できるけど、改行有無なんて、改行なしが必要なときはそればっかりだし、改行アリが必要なときはこれまたそればっかりになる傾向が強いから、毎度書いてられない。
  • デフォルトがend=""だったらいいのに。そうすれば自分はend="\n"なんて使わずにprint("〜\n")ってやるだろうし。
  • 改行有無を動的に変えたいなんて欲求はそもそもほとんどない。引数で渡す意味なんてほとんどない。
  • printとprintlnとかになっていればよかったのに。

こんな私から見ると、py3kのprint関数は、2.xのprint文を引きずらざるを得なくて、中途半端に拡張しましたって思えてしまう。
だから自分ならwriteだとかechoだとかっていう名称でデフォルトが改行しないprintを作るんだろうなと思う。

def echo(*s, **opt):
  return print(end="", *s, **opt)

echo(end=xx)とかやられたらアウトだけど、とりあえずの希望を満たすには悪くない感じ。



2009/06/02追記 functools.partialとかwriteとかの突っ込みがあったので追記してみる。

(1)write()をベースにしたら?

確かにそう思う。でもwriteって、結構めんどくさい。(すまぬ)

import sys
sys.stdout.write("〜")

でもこれが正解だと思う。Python2ではそうやってるし。(他の方法があるのかな)
ただ気になるのはバッファリング。printと混在して出力順序保証されるのかなといった事。今のところ大丈夫そうだけど。ということで、こうかな。

import sys
def write(*msgs):
  for msg in msgs:
    sys.stdout.write(msg)
(2)functools.partialどうよ?

初出のライブラリなんで調べてみたり。なるほど、カリー化ということか(実はよく判ってないかも)。カリー化する際の引数の評価タイミングって、多分いやんな感じなんだろうな、とか勝手に想像しつつ、今回の課題は無関係だからととりあえず。

import functools
write = functools.partial(print, end="")

これなら

write("abc",123, sep="", end="//")

とかやってもOK。
行末が改行の場合はprint関数、それ以外ならwrite関数。と住み分けることで個人的には胃の腑に落ちたといったところ。おつきあい頂いてありがとうです。d:id:methaneさん。