2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[メモ] 初めてのPython

Last updated at Posted at 2017-12-01

概要

初めてのPythonの備忘録です. 学んだことを随時追記していきます.

2018/4/2 追記

当初は身についてないことなどを整理する意味も兼ねて書いていました.
しかし文量が多すぎるので私が理解するのに時間がかかったところ, 書籍のコードでエラーをはいたところ, を備忘録として残すことにしました.

環境/参考資料

5 数値

5.3 数値の使用例

5.3.7 16進数と8進数

16進数は先頭に0x, 8進数は先頭に0oをつけます.

In [1]: 0o01, 0o010, 0o0100
Out[1]: (1, 8, 64)

In [2]: 0x01, 0x10, 0xff
Out[2]: (1, 16, 255)

6 ダイナミックな型付け

6.2 共有リファレンス

6.2.2 「同等」と「同一」

  • ==演算子はオブジェクトが同等か比較するためのものです.
  • is演算子はオブジェクトが同一か比較するためのものです.

わかりにくいので実際に見てみます.

In [32]: L = [1, 2, 3]

In [33]: M = L

In [34]: L == M
Out[34]: True

In [35]: L is M
Out[35]: True

In [36]: L = [1, 2, 3]

In [37]: M = [1, 2, 3]

In [38]: L == M
Out[38]: True

In [39]: L is M
Out[39]: False

つまりLMのオブジェクトが同じなら同等, リファレンスが同じなら同一ということです.
ただし同様のことを小さい数値に対して行うと, 結果が異なる場合があります.

In [40]: x = 42

In [41]: y = 42

In [42]: x == y
Out[42]: True

In [43]: x is y
Out[43]: True

小さい数値や文字列はキャッシュされ再利用されるためです.

あるオブジェクトにいくつのリファレンスがあるか確認した場合は, getrefcount関数を使います.

In [1]: import sys

# オブジェクト42へのリファレンスの数
In [2]: sys.getrefcount(42)
Out[2]: 21

# 新たにオブジェクト42へのリファレンスを追加
In [3]: x = 42

# 新たに追加したので22を返します.
In [4]: sys.getrefcount(42)
Out[4]: 22

9 タプル, ファイルオブジェクト, その他

9.2 ファイル

9.2.3 ファイルオブジェクトの使用例

pickleによりオブジェクトをそのままファイルに保存する

pickleモジュールを使用すれば, Pythonのあらゆるオブジェクトを文字列に変換することなくファイルに直接保存できます.
なおpickleモジュールは, Python2とPython3で仕様が変わったようです. ここではPython3での使用例を示します.

In [1]: F = open('datafile.txt', 'wb')

In [2]: import pickle

In [3]: D = ['spma', 10, [1, 2], {'a': 1, 'b': 2}]

# pickleを利用してオブジェクトDをファイルに保存
In [4]: pickle.dump(D, F)

In [5]: F.close()

In [8]: F = open('datafile.txt', 'rb')

# ファイルからオブジェクトを取り出す
In [9]: E = pickle.load(F)

In [10]: E
Out[10]: ['spma', 10, [1, 2], {'a': 1, 'b': 2}]

# バイトストリーム形式のデータ
In [12]: open('datafile.txt', 'rb').read()
Out[12]: b'\x80\x03]q\x00(X\x04\x00\x00\x00spmaq\x01K\n]q\x02(K\x01K\x02e}q\x03(X\x01\x00\x00\x00bq\x04K\x02X\x01\x00\x00\x00aq\x05K\x01ue.'

11 代入ステートメント, 式ステートメント, printステートメント

11.3 printステートメント

11.3.3 >>を使用したリダイレクト

sys.stdoutに対応するオブジェクトを変更することで出力テキストをリダイレクトする手法はよく用いられます.
しかしこの手法での問題は, 出力先を元の標準出力ストリームに戻したくてもそれが簡単にできない点です.
以下のように工夫することが可能です.

>>> import sys
>>> temp = sys.stdout
>>> sys.stdout = open('log.txt', 'a')
>>> print('spam')
>>> print(1, 2, 3)
>>> sys.stdout.close()
>>> sys.stdout = temp
>>> print('back here')
back here
>>> print(open('log.txt').read())
spam
1 2 3

なお私は簡単なコードの確認にipythonを使っていますが, ipythonだと下記のエラーが出ました.

In [1]: import sys

In [2]: temp = sys.stdout

In [3]: sys.stdout = open('log.txt', 'a')
print('spam')
print(1, 2, 3)
sys.stdout.close()
WARNING:
********
You or a %run:ed script called sys.stdin.close() or sys.stdout.close()!
Exiting IPython!

これは正常な動作のようで, ipythonでsys.stdout.close()をすると標準出力ストリームでも出力できなくなるようです.

話がそれましたが, 以下の方法で簡単にすることが可能です.

In [1]: log = open('log.txt', 'w')

In [3]: print("1, 2, 3", file=log)

In [4]: print("4, 5, 6", file=log)

In [5]: log.close()

In [6]: print(7, 8, 9)
7 8 9

In [7]: print(open('log.txt').read())
1, 2, 3
4, 5, 6

Python3では>>は使えません. print("test", file=sys.stdout)のように出力先をfileで指定することで同様のことができます.
この方法は標準エラーストリームにエラーメッセージを出力する際によく使用されます.

21 モジュールに関連する高度なテクニック

21.6 相対インポートの構文

fromステートメントで.を使ってインポートすることもできます. これを明示的な相対インポートといいます.
.で現在および親パッケージを指定します.
例えば以下のパッケージがあったとします.

  • sound/
    • __init__.py
    • formats/
      • __init__.py
      • wavread.py
      • ...
    • effects/
      • __init__.py
      • echo.py
      • surrond.py
      • ...
    • filters/
      • __int__.py
      • equalizer.py
      • ...

通常インポートする場合は, 以下のようになります.

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

相対インポートの場合, 以下のようになります.

from . import echo
from .. import formats
from ..filters import equalizer

しかしsurround.pyの中でecho.pyを相対インポートした際に以下のエラーがでました.

% python surround.py
Traceback (most recent call last):
  File "surround.py", line 1, in <module>
    from . import echo
SystemError: Parent module '' not loaded, cannot perform relative import

上記の原因はsuuround.pyがメインモジュールになり, つまり__name____main__になり__name__.rpartition('.')[0]が空の文字列を返すためです.
相対インポートできないか試行錯誤しましたが良い方法がみつからなかったので, モジュールサーチパスを設定してインポートをした方が良いと思われます.

24 クラスのコーディング

24.4 演算子のオーバーロード

24.4.4 独自イテレータの作成

ここの例で紹介されているクラスSquaresは自分の環境ではエラーが出て動きませんでした.
next(self)__next__(self)と書き直したらOKでした.
Python3では__next__をつかうようです.

24.4.5 __getattr____setattr__

記載のクラスemptyはPython3では以下のように変更します.
raise AttributeError, attrnameraise AttributeError(attrname)にします.
Python3では上記のようにエラーメッセージは括弧で囲みます.

class empty:
	def __getattr__(self, attrname):
		if attrname == "age":
			return 40
		else:
			raise AttributeError(attrname)

27 例外の基礎

27.2 例外処理の基本

Python3.0以降ではクラス例外が必須です.
以下のコードはエラーが出ます. class Bad: passclass Bad(Exception): passに変更すると動作します.

>>> class Bad: pass
>>> def doomed(): raise Bad()
>>> try:
>>> 	doomed()
>>> except Bad:
>>> 	print('got bad')

27.6 raiseステートメント

27.6.2 例外とともにデータを渡す

raiseステートメントで渡されるデータを確認します.

# raisedata.py
def raiser1():
	raise Exception("hello")

def raiser2():
	raise Exception

def tryer(func):
	try:
		func()
	except Exception as inst:
		print('got this:', inst) 

実行結果は以下の通りです.

In [1]: from raisedata import *

In [2]: tryer(raiser1)
hello

In [3]: tryer(raiser2)

except節では, 例外名の後に変数を指定することができます. この値は例外インスタンスに結び付けられており, instance.argsに例外インスタンスの引数が入っています.

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?