overlaps - title plt python
DivisiĆ³n multiplataforma de camino en python (8)
Alguien dijo "use os.path.split
". Esto se eliminó por desgracia, pero es la respuesta correcta.
os.path.split (ruta)
Divida la ruta de la ruta de acceso en un par, (cabeza, cola) donde cola es el último componente de la ruta de acceso y la cabeza es todo lo que conduce a eso. La parte de la cola nunca contendrá una barra oblicua; Si el camino termina en una barra, la cola estará vacía. Si no hay una barra en el camino, la cabeza estará vacía. Si el camino está vacío, tanto la cabeza como la cola están vacías. Las barras inclinadas se eliminan de la cabeza a menos que sea la raíz (solo una o más barras). En todos los casos, join (head, tail) devuelve una ruta a la misma ubicación que la ruta (pero las cadenas pueden diferir).
Así que no se trata solo de dividir el nombre de archivo y el nombre de archivo. Puede aplicarlo varias veces para obtener la ruta completa de manera portátil y correcta. Ejemplo de código:
dirname = path
path_split = []
while True:
dirname, leaf = split(dirname)
if leaf:
path_split = [leaf] + path_split #Adds one element, at the beginning of the list
else:
#Uncomment the following line to have also the drive, in the format "Z:/"
#path_split = [dirname] + path_split
break
Por favor, acredite al autor original si esa respuesta se recupera.
Me gustaría algo que tenga el mismo efecto que este:
>>> path = "/foo/bar/baz/file"
>>> path_split = path.rsplit(''/'')[1:]
>>> path_split
[''foo'', ''bar'', ''baz'', ''file'']
Pero eso funcionará con las rutas de Windows también. Sé que hay un os.path.split()
pero eso no hace lo que quiero y no vi nada que lo haga.
Aquí hay una implementación explícita del enfoque que solo utiliza iterativamente os.path.split
; utiliza una condición de terminación de bucle ligeramente diferente a la respuesta aceptada.
def splitpath(path):
parts=[]
(path, tail)=os.path.split( path)
while path and tail:
parts.append( tail)
(path,tail)=os.path.split(path)
parts.append( os.path.join(path,tail) )
return map( os.path.normpath, parts)[::-1]
Esto debería satisfacer os.path.join( *splitpath(path) )
es la path
en el sentido de que ambos indican el mismo archivo / directorio.
Probado en linux:
In [51]: current=''/home/dave/src/python''
In [52]: splitpath(current)
Out[52]: [''/'', ''home'', ''dave'', ''src'', ''python'']
In [53]: splitpath(current[1:])
Out[53]: [''.'', ''dave'', ''src'', ''python'']
In [54]: splitpath( os.path.join(current, ''module.py''))
Out[54]: [''/'', ''home'', ''dave'', ''src'', ''python'', ''module.py'']
In [55]: splitpath( os.path.join(current[1:], ''module.py''))
Out[55]: [''.'', ''dave'', ''src'', ''python'', ''module.py'']
ntpath
mano algunas de las rutas de DOS, usando el módulo os.path
con ntpath
, me parece bien, pero no estoy muy familiarizado con los entresijos de las rutas de DOS.
Así que sigue usando os.path.split hasta que llegues a lo que quieres. Aquí hay una implementación fea que usa un bucle infinito:
import os.path
def parts(path):
components = []
while True:
(path,tail) = os.path.split(path)
if tail == "":
components.reverse()
return components
components.append(tail)
Pegue eso en parts.py, importe partes, y listo:
>>> parts.parts("foo/bar/baz/loop")
[''foo'', ''bar'', ''baz'', ''loop'']
Probablemente una implementación más agradable utilizando generadores o recursión por ahí ...
El OP especificado "también funcionará con las rutas de Windows". Hay algunas arrugas con las rutas de Windows.
En primer lugar, Windows tiene el concepto de unidades múltiples, cada una con su propio directorio de trabajo actual, y ''c:foo''
y ''c://foo''
menudo no son lo mismo. Por lo tanto, es una muy buena idea separar primero cualquier designador de unidad, utilizando os.path.splitdrive (). Luego, la drive + os.path.join(*other_pieces)
puede volver a montar la ruta (si es necesario) correctamente drive + os.path.join(*other_pieces)
En segundo lugar, las rutas de Windows pueden contener barras o barras invertidas o una mezcla. En consecuencia, el uso de os.sep
al analizar una ruta no normalizada no es útil.
Más generalmente:
Los resultados producidos para ''foo''
y ''foo/''
no deben ser idénticos.
La condición de terminación del bucle parece expresarse mejor como "os.path.split () trató su entrada como no dividible".
Aquí hay una solución sugerida, con pruebas, que incluye una comparación con la solución de @ Spacedman
import os.path
def os_path_split_asunder(path, debug=False):
parts = []
while True:
newpath, tail = os.path.split(path)
if debug: print repr(path), (newpath, tail)
if newpath == path:
assert not tail
if path: parts.append(path)
break
parts.append(tail)
path = newpath
parts.reverse()
return parts
def spacedman_parts(path):
components = []
while True:
(path,tail) = os.path.split(path)
if not tail:
return components
components.insert(0,tail)
if __name__ == "__main__":
tests = [
'''',
''foo'',
''foo/'',
''foo//',
''/foo'',
''//foo'',
''foo/bar'',
''/'',
''c:'',
''c:/'',
''c:foo'',
''c:/foo'',
''c:/users/john/foo.txt'',
''/users/john/foo.txt'',
''foo/bar/baz/loop'',
''foo/bar/baz/'',
''//hostname/foo/bar.txt'',
]
for i, test in enumerate(tests):
print "/nTest %d: %r" % (i, test)
drive, path = os.path.splitdrive(test)
print ''drive, path'', repr(drive), repr(path)
a = os_path_split_asunder(path)
b = spacedman_parts(path)
print "a ... %r" % a
print "b ... %r" % b
print a == b
y aquí está la salida (Python 2.7.1, Windows 7 Pro):
Test 0: ''''
drive, path '''' ''''
a ... []
b ... []
True
Test 1: ''foo''
drive, path '''' ''foo''
a ... [''foo'']
b ... [''foo'']
True
Test 2: ''foo/''
drive, path '''' ''foo/''
a ... [''foo'', '''']
b ... []
False
Test 3: ''foo//'
drive, path '''' ''foo//'
a ... [''foo'', '''']
b ... []
False
Test 4: ''/foo''
drive, path '''' ''/foo''
a ... [''/'', ''foo'']
b ... [''foo'']
False
Test 5: ''//foo''
drive, path '''' ''//foo''
a ... [''//', ''foo'']
b ... [''foo'']
False
Test 6: ''foo/bar''
drive, path '''' ''foo/bar''
a ... [''foo'', ''bar'']
b ... [''foo'', ''bar'']
True
Test 7: ''/''
drive, path '''' ''/''
a ... [''/'']
b ... []
False
Test 8: ''c:''
drive, path ''c:'' ''''
a ... []
b ... []
True
Test 9: ''c:/''
drive, path ''c:'' ''/''
a ... [''/'']
b ... []
False
Test 10: ''c:foo''
drive, path ''c:'' ''foo''
a ... [''foo'']
b ... [''foo'']
True
Test 11: ''c:/foo''
drive, path ''c:'' ''/foo''
a ... [''/'', ''foo'']
b ... [''foo'']
False
Test 12: ''c:/users/john/foo.txt''
drive, path ''c:'' ''/users/john/foo.txt''
a ... [''/'', ''users'', ''john'', ''foo.txt'']
b ... [''users'', ''john'', ''foo.txt'']
False
Test 13: ''/users/john/foo.txt''
drive, path '''' ''/users/john/foo.txt''
a ... [''/'', ''users'', ''john'', ''foo.txt'']
b ... [''users'', ''john'', ''foo.txt'']
False
Test 14: ''foo/bar/baz/loop''
drive, path '''' ''foo/bar/baz/loop''
a ... [''foo'', ''bar'', ''baz'', ''loop'']
b ... [''foo'', ''bar'', ''baz'', ''loop'']
True
Test 15: ''foo/bar/baz/''
drive, path '''' ''foo/bar/baz/''
a ... [''foo'', ''bar'', ''baz'', '''']
b ... []
False
Test 16: ''//hostname/foo/bar.txt''
drive, path '''' ''//hostname/foo/bar.txt''
a ... [''//'', ''hostname'', ''foo'', ''bar.txt'']
b ... [''hostname'', ''foo'', ''bar.txt'']
False
Python 3.4 introdujo un nuevo módulo pathlib
. pathlib.Path
proporciona métodos relacionados con el sistema de archivos, mientras que pathlib.PurePath
opera completamente independiente del sistema de archivos:
>>> from pathlib import PurePath
>>> path = "/foo/bar/baz/file"
>>> path_split = PurePath(path).parts
>>> path_split
(''//', ''foo'', ''bar'', ''baz'', ''file'')
Puede usar PosixPath y WindowsPath explícitamente cuando lo desee:
>>> from pathlib import PureWindowsPath, PurePosixPath
>>> PureWindowsPath(path).parts
(''//', ''foo'', ''bar'', ''baz'', ''file'')
>>> PurePosixPath(path).parts
(''/'', ''foo'', ''bar'', ''baz'', ''file'')
Y, por supuesto, también funciona con las rutas de Windows:
>>> wpath = r"C:/foo/bar/baz/file"
>>> PurePath(wpath).parts
(''C://', ''foo'', ''bar'', ''baz'', ''file'')
>>> PureWindowsPath(wpath).parts
(''C://', ''foo'', ''bar'', ''baz'', ''file'')
>>> PurePosixPath(wpath).parts
(''C://foo//bar//baz//file'',)
>>>
>>> wpath = r"C:/foo/bar/baz/file"
>>> PurePath(wpath).parts
(''C://', ''foo'', ''bar'', ''baz'', ''file'')
>>> PureWindowsPath(wpath).parts
(''C://', ''foo'', ''bar'', ''baz'', ''file'')
>>> PurePosixPath(wpath).parts
(''C://foo'', ''bar'', ''baz'', ''file'')
¡Huzzah para desarrolladores de Python mejora constantemente el lenguaje!
Un intento más con la opción maxplit, que es un reemplazo para os.path.split ()
def pathsplit(pathstr, maxsplit=1):
"""split relative path into list"""
path = [pathstr]
while True:
oldpath = path[:]
path[:1] = list(os.path.split(path[0]))
if path[0] == '''':
path = path[1:]
elif path[1] == '''':
path = path[:1] + path[2:]
if path == oldpath:
return path
if maxsplit is not None and len(path) > maxsplit:
return path
Utilice la funcionalidad provista en os.path
, por ejemplo
os.path.split(path)
Como escrito en otra parte, puedes llamarlo varias veces para dividir rutas más largas.
Utilice la funcionalidad provista en os.path, por ejemplo
os.path.split(path)
(Esta respuesta fue de otra persona y se eliminó de forma incorrecta e misteriosa, ya que es una respuesta práctica; si desea dividir cada parte de la ruta de acceso, puede llamarla varias veces y cada llamada retirará un componente del final). .)