pathlib
でファイルをコピーしようとしました
import pathlib
import shutil
my_file=pathlib.Path('/etc/hosts')
to_file=pathlib.Path('/tmp/foo')
shutil.copy(my_file, to_file)
私はこの例外を受け取ります:
/home/foo_egs_d/bin/python /home/foo_egs_d/src/test-pathlib-copy.py
Traceback (most recent call last):
File "/home/foo_egs_d/src/test-pathlib-copy.py", line 6, in <module>
shutil.copy(my_file, to_file)
File "/usr/lib/python2.7/shutil.py", line 117, in copy
if os.path.isdir(dst):
File "/home/foo_egs_d/lib/python2.7/genericpath.py", line 41, in isdir
st = os.stat(s)
TypeError: coercing to Unicode: need string or buffer, PosixPath found
Process finished with exit code
... Python 2.7でpathlibを使用してファイルをコピーする方法
これはどうですか?
_import pathlib
import shutil
my_file = pathlib.Path('/etc/hosts')
to_file = pathlib.Path('/tmp/foo')
shutil.copy(str(my_file), str(to_file))
_
問題は、Unix/Linuxを使用している場合は_pathlib.Path
_ PosixPath
オブジェクトを作成し、Microsoft Windowsを使用している場合はWindowsPath
オブジェクトを作成することです。
ただし、shutil.copy()
には引数として文字列が必要です。したがって、ここでstr()
を使用してください。Path
オブジェクトでstr()
関数を使用すると、元のパスが返されます。
shutil.copy()
が機能しない原因は、最新のPythonを使用していないことです。Python 3.6 shutil.copy()
can handle Path
オブジェクト(またはそのサブクラス)Pythonの古いバージョンでは、これはエラーをスローします。これは、shutil
の実装がcopy
、および_pathlib.Path
_型の引数ではありません。
あなたが実際に書きたいのは:
_my_file.copy(to_file)
_
Pathをサブクラス化してこのようなメソッドを含め、_my_file
_の作成を適応させることができます。既存の_pathlib.Path
_に移植/猿パッチ/ダックパンチする方が簡単だと思います
_from pathlib import Path
def _copy(self, target):
import shutil
assert self.is_file()
shutil.copy(str(self), str(target)) # str() only there for Python < (3, 6)
Path.copy = _copy
_
このコードは、Path
インスタンスの_.copy
_メソッドを呼び出す前に実行される限り、好きな場所に置くことができます。 .copy()
の引数には、ファイルまたはディレクトリを指定できます。
Python 3.5、shutil
をインポートせずに、以下を実行できます。
_from pathlib import Path
dest = Path('dest')
src = Path('src')
dest.write_bytes(src.read_bytes()) #for binary files
dest.write_text(src.read_text()) #for text files
_
Python 2.7、 _pathlib2
_ は、_read_bytes
_、_read_text
_、_write_bytes
_、および_write_text
_を提供しますメソッド。
ファイルはメモリにロードされるため、この方法はマシンで利用可能なメモリよりも大きいファイルには適していません。
コメントによると、_write_bytes
_と_read_bytes
_を使用してテキストファイルをコピーできますが、コピー時にエンコードを処理する必要がある場合は_write_text
_と_read_text
_が有利です2つの追加パラメーター:
encoding
は、ファイルのデコードまたはエンコードに使用されるエンコードの名前ですerrors
は、エンコードおよびデコードエラーの処理方法を指定するオプションの文字列です。両方とも open()
と同じ意味を持ちます。
shutil
がどのように変換されてPython 3.6)の_pathlib.Path
_オブジェクトを受け入れるか
https://stackoverflow.com/a/40319071/895245 shutil in Python 3.6は_pathlib.Path
_オブジェクトを取ることができます。
これは非常に魔法のように感じられたため、実装方法を少し調べて、この魔法を自分のクラスで再利用できるかどうかを確認することにしました。
改善はPEP 519の結果でした: https://www.python.org/dev/peps/pep-0519/
これにより多くのstdlib機能が一般化され、結果としてドキュメントは一貫して更新されませんでした。ほとんどのshutil
は3.7 単一の関数でサポートされるドキュメントのみ です。ダイナミックタイピングの喜びへようこそ。
文書化されている場合、stlibは「パスのようなオブジェクト」の用語集にリンクしています。 https://docs.python.org/3/glossary.html#term-path-like-object
ファイルシステムパスを表すオブジェクト。パスのようなオブジェクトは、パスを表すstrまたはbytesオブジェクト、またはos.PathLikeプロトコルを実装するオブジェクトです。 os.PathLikeプロトコルをサポートするオブジェクトは、os.fspath()関数を呼び出すことにより、strまたはbytesファイルシステムパスに変換できます。代わりに、os.fsdecode()およびos.fsencode()を使用して、それぞれstrまたはbytesの結果を保証できます。 PEP 519で導入されました。
そして、それは_os.PathLike
_のドキュメントにリンクします: https://docs.python.org/3/glossary.html#term-path-like-object
ファイルシステムパスを表すオブジェクトの抽象基本クラス。 pathlib.PurePath。
バージョン3.6の新機能。
abstractmethod __fspath__()
オブジェクトのファイルシステムパス表現を返します。
このメソッドはstrまたはbytesオブジェクトのみを返す必要があり、優先度はstrです。
主要な実装のコミットは次のようです:
Modules/posixmodule.c
_の最下位レベルのパス操作ポイントを変更します__fspath__
_を_pathlib.PurePath
_に追加します独自のパスのようなクラスを実装する場合は、次のように実行できます。
_#!/usr/bin/env python3
class MyPath:
def __init__(self, path):
self.path = path
def __fspath__(self):
return self.path
with open(MyPath('f'), 'w'):
pass
_
テスト済みPython 3.6.7、Ubuntu 18.10。
Shutil.move()の代わりに pathlib renameメソッドを使用できます。
import pathlib
my_file = pathlib.Path('/etc/hosts')
to_file = pathlib.Path('/tmp/foo')
my_file.rename(to_file)