プログラミングを趣味にしたい

UE4、scala、ゲーム作り、webアプリ制作とか手を出しているPC系趣味について書き溜めるブログ。現在大規模改装中

このブログは現在リブート中です。 予告なく変更、削除、停止を行う場合があります。
回収作業が終わったらこの文章は削除します

pythonでPathlibをつかってshutil.moveしたときにAttributeErrorすることを回避する。python備忘録

細々としたファイルの操作はすべてpythonにまかせておきたい今日このごろ。
前回前々回と仕事時代を思い出しながら作業用のバッチを書いてました。
tec.citrussin.com
tec.citrussin.com

それはそうとして。
私はpythonでのパス操作は基本的にPathlibを使うんですが、python3.6の私の環境でPathlibを使って、shutil.moveでファイルを移動しようとするとエラーが出るんですよ。

AttributeError: 'WindowsPath' object has no attribute 'rstrip'

でもcopyでは出ない(;・∀・)
ということでずっとcopyを使って、残ったファイルはすべて最後に削除してました。

が、そろそろ何とかしたかったのでちょっとエラー文を読んでエラー回避しました備忘録。


問題

まぁ例えばですよ
Path(p)上にfilenameというフォルダを作って、そこにPath(b)のファイルを入れる場合

・・・エラーチェック省略・・・
#filenameというフォルダを作る。
dirpath = Path(p) / filename
os.mkdir(dirpath)

#Path(b)をdirpathに移動
shutil.move(Path(p) , Path(dirpath))

ってするわけですよね?


ですが、これをすると

AttributeError: 'WindowsPath' object has no attribute 'rstrip'

ってエラーが出るわけですよ。

でもshutil.copy(Path(p) , Path(dirpath))では出ない。

これはちょい困る。

原因

で、まぁとりあえず。
「object has no attribute 'rstrip'」と「shutil.moveをpathlibで使っていること」のキーワードで簡単にぐぐると、まぁ出る出るわのpythonBugtracker。


お前バグやったんかい!(;・∀・)

で、下記トラッカーが回答を出していました。(英語)
bugs.python.org


どうやらshutil._basenameの設計がPathlibを入力に取ることを想定していないらしい。
移動先のフルパスを決定する上でrstrip(文字を区切ってくれるメソッド)を使っているんだけど、そのときに誤動作が起きている御様子。
だから、そもそもbasenameを踏ませないようにしてくれとのこと。

つまり、dst(移動先)の指定にちゃんとファイル名までを指定しろということですね。
わかります(^O^)

解決

ファイル名を別名に指定すると当然リネームされてしまうので、同じ名前で打ち込めばいい。

・・・エラーチェック省略・・・
#filenameというフォルダを作る。
dirpath = Path(p) / filename
os.mkdir(dirpath)

#移動先にファイル名を追加 <=new!
dstfile = dirpath / Path(p).name

#Path(b)を移動 <=dstfileを移動先に指定
shutil.move(Path(p) , Path(dstfile))

これであっさり解決しました。

総括

shutil.moveをするときはdst側にもsrcと同じくファイル名を打ち込んどくこと。


っていうか、公式のバグトラッカーさんは問題解決における神だね。
一発で回避できる単なるバグだったという・・。悲しいなぁ。

関連記事

ないよー