2017年04月14日(金) [長年日記]
■ [python] Pythonにおけるパッケージング
久々にPythonを使う。Python製アプリケーションのパッケージングに関してメモ。CentOS 7.3を使っていてPythonのバージョンは2.7.5(古い)。
情報源としては
をまず見るべきなのだと思う。
setuptoolsをインストール
Pythonのパッケージ関連ツールはややこしくてなかなか覚えられないのだけれど、パッケージングを行うにはsetuptoolsを使うのがいいみたい。
setuptoolsはCentOS 7の標準パッケージにもあるけれど、今回はpipも使いたいのでsetuptoolsはpip経由でインストールすることにする。
pipはCentOS 7だと標準パッケージにはなくEPELにはあるみたい。が、今回はこれも使わずget-pip.pyを使ってインストールする。
% python get-pip.py --user
これで ~/.local に色々ファイルが作られる。pipコマンドは ~/.local/bin にインストールされるのでここにパスを通す必要がある。
get-pip.pyはpip以外にもいくつかパッケージをインストールしていて、その中にsetuptoolsも含まれておりこれでsetuptoolsのインストールが完了した。
setup.pyを作る
setuptoolsを使うとPythonアプリケーションのパッケージングを行うスクリプトを簡単に書ける。スクリプトは通常setup.pyという名前にする模様。次のように書いた。
from setuptools import setup, find_packages
setup(
name="oreore",
packages=find_packages(),
)
setup()には引数がたくさんあるのだけれど、ひとまずはnameとpackagesだけ指定すればよさそう。find_packages()は引数に何も指定しないとカレントディレクトリ配下のPythonモジュールを列挙するようだ。
Pythonのコードを用意
適当にPythonのコードを置いてみる。
% tree .
.
├── hello
│ ├── __init__.py
│ └── hello.py
├── setup.py
└── world
├── __init__.py
└── world.py
hello.pyはライブラリではなく実行できるスクリプトだということにする。スクリプトはsetup.pyに指定しておく必要があり、setup.pyのsetup()の引数にscriptsを追加する。
from setuptools import setup, find_packages
setup(
name="oreore",
packages=find_packages(),
scripts=["hello/hello.py"],
)
なお、entry_pointsという引数に"console_scripts"をキーとした辞書を渡すことでモジュール内の関数を呼び出すスクリプトを生成させることができるようで、この仕組みを使う方が推奨されているみたい。だが今回はこれは使わない。
Wheelパッケージを作る
作ったコード群をパッケージングしてみる。パッケージはWheelという形式で作るのがよさそう。setup.pyにbdist_wheelコマンドを指定すると作れる。
% python setup.py bdist_wheel
カレントディレクトリは次のようになった。
% tree .
.
├── build
│ ├── bdist.linux-x86_64
│ ├── lib
│ │ ├── hello
│ │ │ ├── __init__.py
│ │ │ └── hello.py
│ │ └── world
│ │ ├── __init__.py
│ │ └── world.py
│ └── scripts-2.7
│ └── hello.py
├── dist
│ └── oreore-0.0.0-py2-none-any.whl
├── hello
│ ├── __init__.py
│ └── hello.py
├── oreore.egg-info
│ ├── PKG-INFO
│ ├── SOURCES.txt
│ ├── dependency_links.txt
│ └── top_level.txt
├── setup.py
└── world
├── __init__.py
└── world.py
これの dist/oreore-0.0.0-py2-none-any.whl がWheelパッケージ。
パッケージのインストール
作ったwhlファイルのインストールを試してみる。インストールにはpipを使う。
% pip install dist/oreore-0.0.0-py2-none-any.whl --user
これで ~/.local 配下にインストールされる。
- ~/.local/lib/python2.7/site-packages/oreore-0.0.0.dist-info/
- ~/.local/lib/python2.7/site-packages/hello/
- ~/.local/lib/python2.7/site-packages/world/
- ~/.local/bin/hello.py
という風に配置された。
2017年04月15日(土) [長年日記]
■ [python] autopep8でPythonコードのインデント幅を一括で変更する
扱うPythonのコードにおいて、インデント幅が2のファイルと4のファイルが混在しているので4に統一したい。
Vimで開いてggVG= でいけるかと思ったら、おかしなインデントになってしまう。なんでや。
インデント幅を変更するツールを探してみると、autopep8が使えそうだった。
% autopep8 -r --in-place --select=E111 .
とすることで、カレント以下のファイルのインデントを4に変更してくれるみたい。ただし、「インデントされた空行」(という表現でいいのだろうか)を空行に変更することもしてしまうようで、この動作は余計だ。
あと、autopep8だとインデント幅を2に一括変更するようなことはできなさそう。そういうツールは無いのかなあ。
■ [python] Pythonでホームディレクトリの取得
Pythonでホームディレクトリを得るにはos.path.expanduser()を使えばいいのかな。
>>> import os.path
>>> os.path.expanduser("~")
'/home/kenichi'
2017年04月19日(水) [長年日記]
■ [python] Python 2の文字列とUnicode文字列の相互変換
Python 2を使っているのでUnicode文字列を扱わないといけない。変換方法を覚えられないのでメモ。
- 文字列のdecode()メソッドを呼ぶとUnicode文字列を得られる。
- Unicode文字列のencode()メソッドを呼ぶと文字列を得られる。
UnicodeをUTF-8でエンコードして文字列にするということなんだよなあ。
>>> u"こんにちは"
u'\u3053\u3093\u306b\u3061\u306f'
>>> u"こんにちは".encode("utf8")
'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'
>>> u"こんにちは".encode("utf8").decode("utf8")
u'\u3053\u3093\u306b\u3061\u306f'