今さらPython3 (68) - システムコマンド的な

第10章開始!

入門 Python 3

入門 Python 3

ファイルの扱い

まずはファイルを用意する。

>>> fout = open('oops.txt', 'wt')
>>> print('Oops, I created a file.', file=fout)
>>> fout.close()

print()に出力先を指定するオプションがあったのね。

>>> import os
>>> os.path.exists('oops.txt')
True
>>> os.path.exists('./oops.txt')
True
>>> os.path.exists('waffles')
False
>>> os.path.exists('.')
True
>>> os.path.exists('..')
True
>>> 

ファイルやディレクトリが存在しているかを確認。絶対パスでも相対パスでもOK。

>>> print(os.path)
<module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/posixpath.py'>
>>> import sys
>>> sys.path
['', '/Users/ken/PycharmProjects/IntroducingPython3', '/Users/ken/Documents/workspace/TrainDiagram201510', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages']
>>> 

念のため確認しただけ。sys.pathとos.pathは違うよという話です。

>>> name = 'oops.txt'
>>> os.path.isfile(name)
True
>>> os.path.isdir(name)
False
>>> os.path.isdir('.')
True
>>> os.path.isdir('..')
True
>>> 

ディレクトリ(isdir())なのか、ファイル(isfile())なのかを判定する関数ですね。これも時々忘れるので書いておくと、.でカレントディレクトリ、..で親ディレクトリ。

>>> os.path.isabs(name)
False
>>> os.path.isabs('/big/fake/name')
True
>>> os.path.isabs('/big/fake/name/without/a/leading/slash')
True
>>> os.path.isabs('big/fake/name/without/a/leading/slash')
False
>>> 

isabs()で絶対パスかどうかを判定。ただ、実在するかどうかではなくて、絶対パスたる形式になっているかどうかだけ判定している。

ファイル操作

これ、いつもPythonから抜けてやってたよ。もっと早く知りたかった。

>>> import shutil
>>> shutil.copy('oops.txt', 'ohno.txt')
'ohno.txt'
>>> shutil.copy('ohno.txt', 'ohmygod.txt')
'ohmygod.txt'
>>> shutil.move('ohmygod.txt', 'ohmygod2.txt')
'ohmygod2.txt'

ファイルのコピーと移動は、shutil.copy(), shutil.move()を使えると。

>>> os.rename('ohno.txt', 'ohwell.txt')

ファイルのリネームは、os.rename()がある。

>>> os.link('oops.txt', 'yikes.txt')
>>> os.path.isfile('yikes.txt')
True
>>> os.symlink('oops.txt', 'jeepers.txt')
>>> os.path.islink('jeepers.txt')
True
>>> os.path.islink('yikes.txt')
False
>>> 

ハードリンクとシンボリックリンクというのは、よく知らなかったけど、ファイルそのものとは別にリンクを貼ることが出来るんだね。リンクなのでファイルサイズとか見た目で何か分かるかなと思ってls -lで出してみた。

$ ls -l
...
lrwxr-xr-x  1 ken  staff     8 Dec 26 21:59 jeepers.txt -> oops.txt
....
-rw-r--r--  2 ken  staff    24 Dec 26 21:33 oops.txt
....
-rw-r--r--  2 ken  staff    24 Dec 26 21:33 yikes.txt

シンボリックリンク(jeepers.txt)の方は、ファイルサイズも明らかに小さいし、->oops.txtとリンクですよと見て明らかな感じなのに対し、ハードリンク(yikes.txt)の方はファイルサイズは元のファイルと同じだし、イマイチリンク感がないなぁ。でも、Oops.txtの中身を書き換えて試してみると、両方ともファイルの中身は更新されていたので、とりあえずOKということにしておく。

パーミッション、オーナーの変更

今度は、パーミッションの変更ですね。

>>> os.chmod('oops.txt', 0o400)
>>> import stat
>>> os.chmod('oops.txt', stat.S_IRUSR)

この2つは一緒の動き。念のためパーミッションを確認してみる。確かに、オーナーのところだけrが入っている。

-r--------@ 2 ken  staff    42 Dec 26 22:04 oops.txt

オーナーの変更を試す。

>>> os.chown('oops.txt', uid, gid)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
PermissionError: [Errno 1] Operation not permitted: 'oops.txt'

てか、パーミッションで怒られた。本では、oopsだけしているけど、最初の引数はoops.txtなのでは?

>>> os.path.abspath('oops.txt')
'/Users/ken/PycharmProjects/IntroducingPython3/oops.txt'

ファイルの絶対パスを取得する。

>>> os.path.realpath('jeepers.txt')
'/Users/ken/PycharmProjects/IntroducingPython3/oops.txt'

リンクファイルの実体を取得する。

>>> os.remove('oops.txt')
>>> os.path.exists('oops.txt')
False
>>> 

これでファイルが消えましたよ。

ディレクトリ

>>> os.mkdir('poems')
>>> os.path.exists('poems')
True
>>> 
>>> os.rmdir('poems')
>>> os.path.exists('poems')
False
>>> 

ディレクトリの作成と削除ですね。

>>> os.mkdir('poems')
>>> os.listdir('poems')
[]
>>> os.mkdir('poems/mcintyre')
>>> os.listdir('poems')
['mcintyre']
>>> 

os.listdir()でディレクトリの中身が確認できると。

>>> fout = open('poems/mcintyre/the_good_man', 'wt')
>>> fout.write('''Cheerful and happy was his mood,
... He to the poor was kind and good,
... And he oft' times did find them food,
... Also supplies of coal and wood,
... He never spake a word was rude,
... And cheer'd those did o'er sorrows brood,
... He passed away not understood,
... Because no poet in his lays
... Had penned a sonnet in his praise,
... 'Tis sad, but such is world's ways.
... ''')
341
>>> fout.close()
>>> os.listdir('poems/mcintyre')
['the_good_man']
>>> os.listdir('poems')
['mcintyre']

os.listdir()は、直下のディレクトリまたはファイルだけが拾われるみたいだね。

>>> import os
>>> os.chdir('poems')
>>> os.listdir('.')
['mcintyre']
>>> 

os.chdir()で、change directoryですと。

glob()

正規表現の簡易版的なものでいいのかな?

>>> import glob
>>> glob.glob('m*')
['mcintyre']
>>> glob.glob('??')
[]
>>> glob.glob('m??????e')
['mcintyre']
>>> glob.glob('[klm]*e')
['mcintyre']
>>> 

正規表現とは少し違うけど、見れば何となく意味分かるね。

(つづく)