Python | with 文が使える関数を作る
with 文が使える関数をつくる
yield 式のところで with ブロックの内容が実行される
#with_openthebook.py from contextlib import contextmanager class Book(): def __init__(self): self.contents = '' self.isopen = False def open(self): self.isopen = True print('本は開かれた') return self def write(self, contents): if self.isopen: print('本に記録した') self.contents = contents else: print('本は開かれていない\n') def read(self): if self.isopen: print('本には次のように記録されていた') print(self.contents) else: print('本は開かれていない\n') def close(self): self.isopen = False print('本は閉じられた\n') @contextmanager def openthebook(book=None): if book is None: book = Book() book.open() try: yield book finally: book.close() if __name__ == '__main__': with openthebook() as book: book.write('ばなな') book.read() with openthebook(book): book.read()
これを実行すると次のように表示される。
$ python with_openthebook.py 本は開かれた 本に記録した 本は閉じられた 本は開かれた 本には次のように記録されていた ばなな 本は閉じられた 本は開かれていない
Jupyter | configure jupyter qtconsole
jupyter qtconsole をフォント指定して起動
jupyter qtconsole --ConsoleWidget.font_family="MyricaM M" --ConsoleWidget.font_size=12
Python | pdb 対話的デバッガ
(Pdb) プロンプトのコマンド(の例)
プログラムを調べるコマンド
- w(here) スタックトレースを表示、矢印は現在のフレームを表す
- u(p) スコープを関数の呼び出し元に移す (older frame)
- d(own) スコープを一段下に移す (newer frame)
プログラム実行を制御するコマンド
- s(tep) 次の行まで実行、関数が呼ばれた場合は関数内で一時停止
- n(ext) 次の行に達するか、関数が返るまで実行を続行
- r(eturn) 現在の関数が帰るまで実行
- c(ontinue) 次のブレークポイントまで実行
[参考文献]
27.3. pdb — The Python Debugger — Python 3.5.2 documentation
Effective Python ―Pythonプログラムを改良する59項目
- 作者: Brett Slatkin,石本敦夫,黒川利明
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/01/23
- メディア: 大型本
- この商品を含むブログ (4件) を見る
Python | python コードのテスト
unittest を使う
# utils.py def to_hex(integer, length, byteorder, *, signed=False): b = integer.to_bytes(length, byteorder, signed=signed) lst = ['{:02X}'.format(x) for x in b] return ''.join(lst) # test_to_hex.py from unittest import TestCase, main from utils import to_hex class UtilsTestCase(TestCase): def test_to_hex_1byte(self): self.assertEqual('9C', to_hex(-100, 1, 'big', signed=True)) def test_to_hex_2byte_little(self): self.assertEqual('18FC', to_hex(-1000, 2, 'little', signed=True)) def test_to_hex_2byte_big(self): self.assertEqual('FC18', to_hex(-1000, 2, 'big', signed=True)) def test_to_hex_1byte_unsigned(self): self.assertEqual('64', to_hex(100, 1, 'little')) def test_to_hex_2byte_unsigned_little(self): self.assertEqual('E803', to_hex(1000, 2, 'little')) def test_to_hex_2byte_unsigned_big(self): self.assertEqual('03E8', to_hex(1000, 2, 'big')) def test_to_hex_not_int(self): self.assertRaises(AttributeError, to_hex, object(), 2, 'big', signed=True) def test_to_hex_overflow(self): self.assertRaises(OverflowError, to_hex, -1000, 1, 'big', signed=True) def test_to_hex_overflow2(self): self.assertRaises(OverflowError, to_hex, -1000, 2, 'big', signed=False) if __name__ == '__main__': main()
Python | 2の補数 (signed) int ⇔ bytes ⇔ str (16進文字列)
(signed) int → bytes
int.to_bytes を使う
>>> (-100).to_bytes(1, byteorder='little', signed=True) b'\x9c' >>> (-1000).to_bytes(2, 'little', signed=True) b'\x18\xfc' >>> (-1000).to_bytes(2, 'big', signed=True) b'\xfc\x18'
struct.pack を使う
>>> import struct >>> struct.pack('b', -100) b'\x9c' >>> strckt.pack('h', -1000) # little endian b'\x18\xfc' >>> strckt.pack('>h', -1000) # big endian b'\xfc\x18'
bytes → str (16進文字列)
>>> b = b'\x9c' >>> '{:02X}'.format(b[0]) '9C' >>> b = b'\xfc\x18' >>> '{:02X}{:02X}'.format(b) 'FC18' >>> lst = ['{:02X}'.format(x) for x in b] >>> lst ['FC', '18'] >>> ''.join(lst) # big endian 'FC18' >>> lst.reverse() >>> lst ['18', 'FC'] >>> ''.join(lst) # little endian '18FC'
str (16進文字列) → bytes
>>> n = int('9C', 16) >>> n.to_bytes(1, byteorder='big') b'\x9c' >>> n = int('FC18', 16) >>> n.to_bytes(2, byteorder='big') b'\xfc\x18' >>> n = int('18FC', 16) >>> n.to_bytes(2, byteorder='little') b'\xfc\x18'
bytes → (signed) int
int.from_bytes を使う
>>> int.from_bytes(b'\x9c', byteorder='big', signed=True) -100 >>> int.from_bytes(b'\xfc\x18', 'big', signed=True) -1000 >>> int.from_bytes(b'\x18\xfc', 'little', signed=True) -1000
struct.unpack を使う
>>> import struct >>> struct.unpack('b', b'\x9c')[0] -100 >>> struct.unpack('>h', b'\xfc\x18')[0] # big endian -1000 >>> struct.unpack('h', b'\x18\xfc')[0] # little endian -1000
Python | 2の補数のビットパターンを文字列で得る方法
str.format を使う
>>> '{:08b}'.format(-100 & 0xff) '10011100' >>> '{:02X}'.format(-100 & 0xFF) '9C' >>> '{:02X}'.format(-1000 & 0xFFFF) 'FC18'
int.to_bytes を使う
>>> b = (-100).to_bytes(1, byteorder='little', signed=True) >>> b b'\x9c' >>> '{:02X}'.format(b[0]) '9C' >>> b = (-1000).to_bytes(2, 'little', signed=True) >>> b b'\x18\xfc' >>> '{:02X}{:02X}'.format(*b) '18FC' >>> b = (-1000).to_bytes(2, 'big', signed=True) >>> b b'\xfc\x18' >>> lst = ['{:02X}'.format(x) for x in b] >>> lst ['FC', '18'] >>> ''.join(lst) 'FC18'
struct を使う
>>> import struct >>> b = struct.pack('b', -100) >>> b b'\x9c' >>> '{:02X}'.format(b[0]) '9C' >>> b = strckt.pack('h', -1000) >>> b b'\x18\xfc' >>> '{:02X}{:02X}'.format(*b) '18FC' >>> b = strckt.pack('>h', -1000) >>> b b'\xfc\x18' >>> lst = ['{:02X}'.format(x) for x in b] >>> lst ['FC', '18'] >>> ''.join(lst) 'FC18'