Python Advent Calendar 2013の13日目です。
Python 3.4ではasyncio
functools.singledispatch
など画期的なライブラリがいくつも追加されています。それはアドベンドカレンダーで皆さんが紹介されている通りです。
そして!その中で最も重要で画期的と言えるのがpathlib
なのです!
11.1. pathlib ― Object-oriented filesystem paths ― Python v3.4.0b1 documentation
まずは、主な使用例を御覧ください
パスの結合(演算子オーバーロードだ!)
>>> from pathlib import Path
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
ファイル属性のチェック
>>> q.exists()
True
>>> q.is_dir()
False
パターンマッチで検索
>>> list(p.glob('**/*.py'))
[PosixPath('test_pathlib.py'), PosixPath('setup.py'),
PosixPath('pathlib.py'), PosixPath('docs/conf.py'),
PosixPath('build/lib/pathlib.py')]
ファイルを開く
>>> with q.open() as f: f.readline()
...
'#!/bin/bash\n'
オブジェクト指向
オブジェクト指向は後付だとかそうでないとか言われたPythonですが、 ファイルパスの操作は初期からずーっと文字列を直接操作、つまり明らかに非オブジェクト指向でした。
しかし、3.4に至ってとうとう pathlib
でパスをオブジェクト指向で扱えるようになります!やったね!
全部入り
いままで、ファイル削除や移動はos
・パターンマッチにはglob
と、いろいろなライブラリに散らばっていました。
pathlibは以下の機能を統合しています。
abspath
join
basename
などのパス操作(os.path
)rename
chmod
listdir
などのファイル操作(os
)- パターンマッチ(
glob
・fnmatch
) - ファイルを開く(
io.open
)
シェルスクリプト代わりに使うなら、8割がたpathlib
で完結するのではないでしょうか?
なお、 tempfile
shutil
subprocess
の機能は含まれていないのですが、
pathlib.Path
は文字列と相互変換できるので、これらともシームレスに運用できます。
path = Path('/usr/bin/python')
from subprocess import check_call
check_call(['ls', '-l', str(path)])
PurePosixPath/PureWindowsPath
LinuxとWindowsではパスの扱いが違います(区切り文字やドライブの存在)。
なので、 pathlib.Path
をインスタンス化すると、実際にはpathlib.PosixPath
かpathlib.WindowsPath
が返されます。Windowsでpathlib.PosixPath
を使ったり、その逆はできません。
しかし、URLのパス部の解析など、Windows上でPosixのパスを扱いたいこともあります。
そんなときは、pathlib.PurePosixPath
・pathlib.PureWindowsPath
を使います。
PurePathはパスを文字列として操作することはできますが、
ファイル移動などのファイルシステムへのアクセス操作はできません。
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pathlib
>>>
>>> # WindowsでPosixPathは使えません
>>> pathlib.PosixPath("foo")
NotImplementedError: cannot instantiate 'PosixPath' on your system
>>> # PurePosixPathは使えます!
>>> pathlib.PurePosixPath("foo")
PurePosixPath('foo')
じつは今までもos.path
に対して、ntpath
posixpath
macpath
があって、
Windows上でUnixのパス操作が出来たのですがマイナーでした。
旧バージョンでも使えます。
pathlibは元々サードパーティのライブラリなので、2.7・3.2・3.3でも使えます。
pathlib : Python Package Index
その他
ところでPathを呼ぶと、OS用のクラスのインスタンス(PosixPathかWindowsPath)が返ります。
Pathをそのままインスタンス化することは、普通の方法ではできません。
>>> pathlib.Path # Pathはクラス
<class 'pathlib.Path'>
>>> pathlib.Path("foo") #でもサブクラスのインスタンスが返る
WindowsPath('foo')
これはPath.__new__
をオーバーライドすることで実現されています。
class Path(PurePath):
__slots__ = (
'_accessor',
'_closed',
)
def __new__(cls, *args, **kwargs):
if cls is Path:
cls = WindowsPath if os.name == 'nt' else PosixPath
self = cls._from_parts(args, init=False)
if not self._flavour.is_supported:
raise NotImplementedError("cannot instantiate %r on your system"
% (cls.__name__,))
self._init()
return self
詳しくはドキュメントを参照して下さい。
他にもpathlibはクラス・property・contextlibなどの基本的なテクニックが詰まっています。 使用目的が分かりやすく、分量も1300行弱ということで、入ってくる新人のコードリーディング課題に最適ではないでしょうか。
Enjoy!