初めてのPython(11章)

代入、出力を行うステートメント

代入ステートメント

『=』の左側(代入先)に「変数」または「オブジェクトの構成要素」、右側(代入対象)に「オブジェクト」を書くことで
代入対象に向かうリファレンスを代入先に作成することが出来る。

代入には、

基本形は通常の代入ステートメント

シーケンス代入

代入対象にシーケンスを指定することで、シーケンスをアンパックして代入する。
代入先の数とシーケンスをアンパックした結果出来上がるオブジェクトの数が一致していることが必要。

タプル代入やリスト代入と別枠で紹介されているが、2つともシーケンス代入の一部なんじゃないかな。
代入先がタプルであろうが、リスト形式であろうが、
アンパックされたものがそれぞれの構成要素に代入され、独立に存在するんだから。

>>> a,b,c,d,e,f = 'string'
>>> a,c,e,b,d,f
('s', 'r', 'n', t', 'i', 'g')
>>> [l1, l2, l3, l4] = ('s', 'p', 'a', 'm')
>>> l1, l2, l3, l4
('s', 'p', 'a', 'm')
>>> (t1, t2, t3, t4) = ['e', 'g', 'g', 's']
>>> [t1, t2, t3, t4]
['e', 'g', 'g', 's']
>>> string = "spam"
>>> x, y, z = string
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> x, y, z = string[0], string[1:3], string[3]
>>> x, y, z
('s', 'pa', 'm')
>>> 
マルチターゲット代入

Cの変数初期化の時によく使うやつ(a = b = c = 0)
複数の代入先に同じ代入対象を代入する操作。
共有リファレンスを作ることになるから、代入対象がmutableなオブジェクトだと注意が必要。
というか、やらない方が後々の自分のためかも、おとなしく別々に代入した方がよいかな。

拡張代入ステートメント

これもCでよく使うやつ(a += 1)
a = a + 1 と書くと a の評価が2回行われるので、それが1回で済むから処理が早い。
リスト*1に対して拡張代入すると、オブジェクトが上書きされる。
共有リファレンスを持ってるオブジェクトにやると大変。

Cでよくつかうやつに、インクリメント/デクリメントがあるけど、これはPythonでは出来ない。
Pythonには、immutableなオブジェクトがいるから上書き処理が必要なインクリメントやデクリメントは出来ない。

拡張代入はその名の通り代入を伴うから、
immutableなオブジェクトでも新しく作成されたオブジェクトに向かってリファレンスを上書きするから問題無し。

printステートメント

オブジェクトの出力を行うステートメント
printステートメントを実行すると、sys.stdout.write()が裏では実行されている。

出力先をstdoutから変える方法が2つ

  1. sys.stdoutに代入されているオブジェクトを変更する
  2. >> を使う

『>>』 は、stdoutにも出したいし、別にも出したい時に便利

sys.stdoutを変更する

sys.stdoutに次のようなオブジェクトを指定することで、指定したオブジェクトが示す先に出力する。

  • ファイルオブジェクト
  • write()メソッドを持つクラスのオブジェクト

下の方については、こんな感じのクラスであればよい

class OutputObject:
    def write(self, string):
        # 出力のためのコード

1回変えると出力先を変更するまで、ずっとそこに出力し続ける変更の仕方。
もとに戻し方は2通り

  • sys.stdout を変更する前に、一時変数に退避して(temp = sys.stdout)、戻したい時に退避したものを代入し直す(sys.stdout = temp)
  • sys.__stdout__属性を代入する
>> を使う

こんな感じで使う

>>> log = open("hoge.txt", "w")
>>> print >> log, 1, 2, 3
>>> log.close()

sys.stdoutの変更同様、『>>』にはファイルオブジェクトとwrite()メソッドを持つクラスのオブジェクトを指定できる。

標準出力、標準エラー出力に出したければ、

>>> import sys
>>> print >> sys.stdout, "output to stdout"
>>> print >> sys.stderr, "output to stderr"

*1:ディクショナリはmutableだけど、四則演算とかの演算子が無いから使えないよね。。。