ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【雑感】「Effective Python」

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

今さっき読み終わった。感想をつらつらと書く。

  • Python初心者にもいいと思うが、個人的なオススメな読者は「Pythonの初心者本を読んで実際にPythonで何か作ってみたx3ぐらい」の人に読んでほしいかも。その方が理解できるはず
    • 初心者にはオススメじゃないの?というわけじゃなくて、Pythonで何か動くものを書いたことがある人が( ゚д゚)ハッ!する内容があるので読んでいて楽しかった
    • 逆に書いたことがない人が読むと「むー?そうなんだ?」的な何かが邪魔して腑に落ちないかもしれない
  • 3章「クラスと継承」はまずまず理解できたが、4章「メタクラスと属性」、5章「並行性と並列性」はまだあんまり触ったことがなかったので、コード書きながら読むと理解しやすいはず。自分は読み物として読んでいたのであまり腑に落ちなかった。なんていえばいいかな?過去のPython書いたときの経験と比較しながら読むと気づきが多くて読んでいて面白い感じ。伝わるかな?
    • しかし4章はよりPythonらしいコードを書くのに必要な項目だと思った。他の言語では当たり前なカプセル化Pythonで実装するにはどうしたらいい?みたいなことをPythonらしい書き方で書けるようになると思う
    • 5章の組み込みモジュール「Queue」の話はまだちゃんと理解していないが、これを使ってwebクローラーを作ってみたいと思った
  • 後半も面白い。6章「組み込みモジュール」7章「共同作業(コラボレーション)」8章「本番運用準備」は仕事でも使えるテクニックが色々のっていてこれまた読んでて( ゚д゚)ハッ!とした内容だった
  • 集中力がない自分は3章〜5章が中々進まずトータル1週間かかったけど、Python好きな人なら多分4時間もあれば読める本だと思う。

この本、PyConJP2017に参加したときにオライリーさんがブースで販売していて、なんとなくで購入したんだけど良書です。Python初心者が中級にあがるために必要だと思った。

まだ全部ちゃんと理解したわけじゃないので、もう一回読むことになるけど、今度はコードを写経しながら読もうと思う。

www.aipacommander.com

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

今「Effective Python」って本読んでいるけど面白い : 【Effective Python】読書ログ1日目

Pythonの技術書ってなんだかんだはじめて読んだかも。

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

まだ2章までしか読んでいないけど、なんかPythonでいい感じの書き方ってどんななだろー? ま、いっか。うごくし。的なことを解決してくれていて、すごく面白く読み進めている。

ちゃんとした感想は読み終えたあとに書くが、ちょこちょこ( ゚д゚)ハッ!とした内容をメモしておく。

  • bytes, str, unicodeの違いを知っておく
    • Python2では誰しもハマるunicodeだけど、理解した上でヘルパー関数を用意して楽しよう
    • よくエラーをキャッチしてはエラー文をググって15分消費するって感じだけど、この本では3Pで理解できる(はず
  • イテレータを並列に処理するにはzipを使う
    • これまでenumerateとか使っていたけど、そういえばzipがあった
  • Noneを返すよりは例外を選ぶ
    • Noneは条件式においてFalseなので、他の値(ゼロ、空文字列)もFalseに評価されるから想定外なケースを引き起こしやすい
    • 例外を上げて、特別な条件を示すようにする。try ~ except使えってこと
  • 動的なデフォルト引数を指定するときにはNoneとドキュメンテーション文字列を使う
    • デフォルト引数は1度しか評価されない。モジュールロード時の関数定義の時だけ
    • びびった話は{}とか[]をいれても1度しか書記されない(なんだと?!!
    • なので、何度も実行した場合、値が初期化されず引き継がれ摩訶不思議なエラーになるとのこと
    • この場合はデフォルト値をNoneにして、コメントで振る舞いを説明しないさいとのこと

久々にPHP叩こうとしたらPHP動かんかった

こんなエラーが…

$ php -v
dyld: Library not loaded: /usr/local/opt/jpeg/lib/libjpeg.9.dylib
  Referenced from: /usr/local/bin/php
  Reason: image not found
Trace/BPT trap: 5

qiita.com

$ brew switch jpeg 9b
Cleaning /usr/local/Cellar/jpeg/8d
Cleaning /usr/local/Cellar/jpeg/9b
17 links created for /usr/local/Cellar/jpeg/9b
$ php -v
Cannot load Xdebug - extension already loaded
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/opt/php56-intl/intl.so' - dlopen(/usr/local/opt/php56-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.57.dylib
  Referenced from: /usr/local/opt/php56-intl/intl.so
  Reason: image not found in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php56-intl/intl.so' - dlopen(/usr/local/opt/php56-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.57.dylib
  Referenced from: /usr/local/opt/php56-intl/intl.so
  Reason: image not found in Unknown on line 0
PHP 5.6.31 (cli) (built: Aug  7 2017 20:28:16)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans

(´・ω・`)

github.com

$ brew uninstall --force php56-intl
$ brew install --force --build-from-source php56-intl
$ php -v
Cannot load Xdebug - extension already loaded
PHP 5.6.31 (cli) (built: Aug  7 2017 20:28:16)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans

えくせれんと!!

$ sudo apachectl -k start
httpd: Syntax error on line 171 of /private/etc/apache2/httpd.conf: Cannot load /usr/local/Cellar/php56/5.6.23/libexec/apache2/libphp5.so into server: dlopen(/usr/local/Cellar/php56/5.6.23/libexec/apache2/libphp5.so, 10): image not found

(´・ω・`)

chaika.hatenablog.com

$ brew uninstall php56
$ brew reinstall php56 --without-ldap --with-httpd24
$ ls  /usr/local/Cellar/php56/5.6.31_7/libexec/apache2/libphp5.so
/usr/local/Cellar/php56/5.6.31_7/libexec/apache2/libphp5.so

確認できた。あとはhttpd.confに書いてあるパスを修正すればおわり。

Numpy <-> Pillow <-> Python file object

集中切れたからブログ書く.

これが良い手法かどうかわからないが、numpyからpillowいったり、Python file objectからpillowいったり、pillowからPython file objectへコンバートしてみた。

環境

  • Python2.7.11
  • numpy==1.13.1
  • Pillow==4.2.1

多分だけど、3系もさほど変わらないと思う。

準備

>>> from PIL import Image
>>> import numpy as np
>>> import io

numpy -> pillow

>>> numpy_object = np.zeros([500, 500])
>>> Image.fromarray(numpy_object)
<PIL.Image.Image image mode=F size=500x500 at 0x103762450>
>>> Image.fromarray(numpy_object, mode='RGB')  # modeで画像のチャネルを指定できる
<PIL.Image.Image image mode=RGB size=500x500 at 0x103996B90>

pillow -> numpy

np.asarray()を使えばおk. 楽.

>>> pillow_object = Image.open('./assets/1.jpg')
>>> np.asarray(pillow_object).shape
(500, 500, 3)

pillow -> Python file object

要はbytes?

>>> pillow_object = Image.open('assets/1.jpg')
>>> buf = io.BytesIO()
>>> pillow_object.save(buf, 'jpeg', quality=25, optimize=True)  # メモリに書き込み。重い
>>> python_file_object = buf.getvalue()

コメントにも書いているけど、これが重い処理。できればこれやめたい。(画像の容量次第だししょうがないのかな。。。)

Python file object -> pillow

>>> f = open('assets/1.jpg')
>>> read_data = f.read()
>>> Image.open(io.BytesIO(read_data))
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=2480x3507 at 0x103DF8710>

これはいい感じで早い。

雑感

pillowにするのは早いけど、pythonのfile objectにするのは遅いのか。。。。?