python関連雑記 ( 反応が微妙だった記事の墓場 )
例外に対する対応 TypeError: expected str, bytes or os.PathLike object
多くの場合は実装ミスだが、エラー自体は 特定のオブジェクトにファイル名として使えることを示唆している。
__fspath__ を実装する
例外に対する対応 TypeError: XXXXXX object is not subscriptable
多くの場合は実装ミスだが、エラー自体は、オブジェクトに配列のふりをさせる可能性を示唆している。
__getitem__(self, n) を実装する
タイムゾーンを指定すると高速になる....わけではない
Python3のdatetimeはタイムゾーンを指定するだけで高速になる - Qiita
記事ではプロファイラをつかってるが、python/3はソース公開してるので、ソースを眺めたほうが早い。処理を順に追いかけてみよう、
タイムゾーンは指定してないので、tz=Noneは確定だとして、
ようやく本命 datetime._fromtimestamp(t,True,None)
この関数の中盤に、明確に tz is Noneに関する処理がある
githubの履歴をたどるとPEP495に対する修正であることがわかる
PEP495
PEP495に関しては、オフィシャルで日本語訳が存在する。
世界の大抵の場所で、地域時計が1日繰り下げられることがこれまでありましたし、これからもあるでしょう。そういった時に、同じ日に同じ時間を指す区間があります。そういった状況では地域時計が表示する (あるいは Python の datetime インスタンスが格納する) 情報では、時間内の特定の瞬間を識別することはできません。
PEP 495 は時間内の地域時間が同じ二つの瞬間を区別するために、新たな fold 属性を datetime.datetime インスタンスならびに datetime.time クラスに追加しました。
早い話が、夏時間対応ということだ。
似たようなことはRubyでも起こるらしい。
Ruby の time.c を見てみると、 find_time_t 関数にてシステムの localtime_r に指定時刻の2時間前後の時刻を与えて、何が返ってくるかを調べています。これはどうやら、夏時間の切り替わりの際には同一の時刻が2回ある場合があるので、そういうときに必ず決まった側を返すための処理のようでした。
decorators in the python standard lib (@deprecated specifically) - Stack Overflow https://stackoverflow.com/questions/2536307/decorators-in-the-python-standard-lib-deprecated-specifically/48632082#48632082
import warnings
def deprecated(message):
def deprecated_decorator(func):
def deprecated_func(*args, **kwargs):
warnings.warn("{} is a deprecated function. {}".format(func.__name__, message),
category=DeprecationWarning,
stacklevel=2)
warnings.simplefilter('default', DeprecationWarning)
return func(*args, **kwargs)
return deprecated_func
return deprecated_decorator
色々なサイトで、python2|3での 画像処理の実装として、ImageMagick/wandをおすすめしてるが、実はやや処理が遅い。
小生の場合、連続して画像処理をさせているスクリプトがあり、straceしてたまたま気づいたのだが結構怪しい処理を色々やってる。
wandとPILで処理時間を比較してみる。
中央にポツンと小さい模様があるだけの 4000バイト以下のモノクロ画像 test.pngを使った例をあげる。増色&減色をするだけの簡単な実装である。
画像の詳細は本件の本質にはあまり影響しないため割愛する。
wandの実装例は次の通り。
import wand
import wand.image
aa = wand.image.Image(filename="test.png")
aa.type = "truecolor"
aa.type = "palette"
#aa.auto_level()
PIL/pillow の実装例は次の通り。
import PIL.Image
aa = PIL.Image.open("test.png")
aa.convert("RGBA")
aa.convert("P")
#aa.auto_level()
これを小生の約7000bogomipsの環境で実行するとこうなる。
$ time python3 p.py
real 0m0.073s
user 0m0.059s
sys 0m0.014s
$ time python3 w.py
real 0m0.454s
user 0m0.440s
sys 0m0.099s
PIL版の0.07秒は十分納得できる数字だが、wand版の0.4秒が明らかに遅いことがわかるだろう。
wandで0.4秒掛かってる理由
紆余曲折あったが、理由はわかった。
Imagemagickのライブラリを探すために複雑な処理をしているためだ。
ctypes.util.find_libraryが曲者なのだが、実は内部でgccを実行して、ライブラリのpathを探そうとしてる。
これは imagemagickの方も問題で、非標準なディレクトリへのインストールも提唱してるためだ。
Set the MAGICK_HOME environment variable to the path where you extracted the ImageMagick files. For example:
$ export MAGICK_HOME="$HOME/ImageMagick-7.1.0"
wand側でもこのあたりの言及はしている。
PIL(pillow)+α で行こう
手っ取り早く、PILで行くことにした。
前述の通り、減色程度ならPILで容易に代替可能である。
また代表的な画像処理であろう crop および resize==transform も類似の機能があるため、概ねPILで実装可能である。
小生の運用では、さらにこれに明度レベル調整が必要だった。 wandでは非常に簡単に使える機能なので、このためだけにwandを使うのなくはない。
auto_levelはPILには機能がないため、自作する必要がある。が、これはすぐ見つかる。例えば次のリンクでは numpy+cv2を使って自分で計算する。
wand/imagemagickを辞めて。PILに加えてopencv+numpyまで使うなら本末転倒では?と思う方も居るだろう。
しかし小生の場合では、それでもwandより何割か処理が早いことを確認した。そのため、wandを廃止してPIL+opencv/numpyに切り替えた。
z80エミュレータpython3実装。デコレータで命令表を実装してるのがなかなかpythonic
import unicodedata
def mb_strimwidth(s, start, width, trimmarker=''):
def char_width(c):
if unicodedata.east_asian_width(c) in 'FWA':
return 2
else:
return 1
end = start + width
current_width = 0
result = ''
for char in s:
current_width += char_width(char)
if current_width > end:
return result + trimmarker
result += char
return result
# 例
text = 'これは非常に長いテキストです'
print(mb_strimwidth(text, 0, 10, '...'))
python page tkinter
呼び出し元を確認するだけのデコレータ。スパゲッティをほぐすのに使う。
出力先を変更できたほうが良い?
2パターン用意するのがちょっとクドイ....
パラメタ付きも考慮するデコレータならクラスで作る方が楽か?
使用例
クラス変数に対するsetterを生やそうとする試み。
archlinuxで今更svn => mercruial 変換
subversion-1.14には python3 bindingが付属
archlinux版mercurialはpython3ビルド。
以上により、現時点でmercurial単体で変換が可能だった