paths - Copiar archivo con pathlib en Python
pathlib python (4)
Intento copiar un archivo con pathlib
import pathlib
import shutil
my_file=pathlib.Path(''/etc/hosts'')
to_file=pathlib.Path(''/tmp/foo'')
shutil.copy(my_file, to_file)
Me sale esta excepción:
/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
... cómo copiar un archivo con pathlib en Python 2.7?
Desde Python 3.5, sin importar shutil
, puedes hacer:
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
Para Python 2.7, pathlib2
proporciona los read_bytes
, read_text
, write_bytes
y write_text
.
El archivo se cargará en la memoria, por lo que este método no es adecuado para archivos más grandes que la memoria disponible de la máquina.
Según los comentarios, uno puede usar write_bytes
y read_bytes
para copiar archivos de texto, pero si necesita lidiar con la codificación en el momento de la copia, write_text
y read_text
presentan la ventaja de dos parámetros adicionales:
-
encoding
es el nombre de la codificación utilizada para decodificar o codificar el archivo -
errors
es una cadena opcional que especifica cómo deben manejarse los errores de codificación y decodificación
Ambos tienen el mismo significado que en open()
.
Entonces, ¿qué pasa con esto?
import pathlib
import shutil
my_file = pathlib.Path(''/etc/hosts'')
to_file = pathlib.Path(''/tmp/foo'')
shutil.copy(str(my_file), str(to_file))
El problema es pathlib.Path
crea un objeto PosixPath
si está usando Unix / Linux, WindowsPath
si está usando Microsoft Windows.
Pero shutil.copy()
necesita una cadena como argumentos. Entonces, use str()
aquí, cuando use la función str()
en un objeto Path
, devolverá la ruta original.
La causa de que shutil.copy()
no funcione es que no está utilizando la shutil.copy()
más reciente de Python. Python 3.6 shutil.copy()
puede manejar objetos de Path
(o subclases de los mismos). Que para las versiones anteriores de Python, esto genera un error porque las implementaciones de shutil
esperan argumentos de cadena para copy
, y no argumentos de tipo pathlib.Path
.
Lo que realmente quieres poder escribir es:
my_file.copy(to_file)
Puede crear una subclase de ruta para incluir dicho método y adaptar la creación de my_file
. Me resulta más fácil simplemente injertar / parche-parche / pathlib.Path
-pato en la pathlib.Path
existente 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
Puede colocar este código en el lugar que desee, siempre que se ejecute antes de llamar al método .copy
en cualquiera de las instancias de Path
. El argumento para .copy()
puede ser un archivo o un directorio.
Puede usar el método de cambio de nombre de pathlib en lugar de shutil.move ().
import pathlib
my_file = pathlib.Path(''/etc/hosts'')
to_file = pathlib.Path(''/tmp/foo'')
my_file.rename(to_file)