2011-10-07 9 views
5

¿Alguien sabe por qué la función os.path.join no funciona con las subclases de str?os.path.join con la subclase str

(estoy usando Python3.2 x64 y x86 Python2.7 en Windows y el resultado es el mismo)

Ese es el código que tengo

class Path(str): 
    def __add__(self, other): 
     return Path(os.path.join(self, other)) 

p = Path(r'C:\the\path') 
d = p + 'some_file.txt' 

y el resultado que quiero:

'C:\\the\\path\\some_file.txt' 

pero la salida es \\some_file.txt sin importar el valor de self.

sé que puedo hacerlo bien str(self) o almacenarla como self.path y utilizar más tarde, pero ¿por qué os.join.path no acepta una subclase str ni generará un error (como cuando se utiliza un número o cualquier tipo no cadena)?

Respuesta

0

En caso de duda, consulte la fuente (Python32 \ Lib \ ntpath.py). los bits pertinentes:

"" "unir dos o más componentes de nombre de ruta, la inserción de '\' según sea necesario Si cualquier componente es una ruta absoluta, todos los componentes de trayectoria anterior serán descartados.. ''" (énfasis añadido)

hacia la parte inferior de la función join está tratando de colocar una \ entre las dos piezas utilizando path += '\\' + b (donde b es some_file.txt) - que primero añade \ y some_file.txt (que son cadenas de fricción), entonces añade que a Path(r'c:\the\path') llamando Path.__add__(r'c:\the\path', r'\some_file.txt'), que será otra vez llamada os.path.join ...

¿Notaste el \ que ahora está en el nombre? Es por eso que la parte inicial del camino se está perdiendo.

Calling os.path.join con str(self) (o self.path) funciona porque entonces os.path.join solamente se está llamando una vez en lugar de dos veces.

1

Parece que os.path.join usa la compilación en el método __add__, esto se puede verificar colocando una instrucción de impresión en el método __add__.

>>> class Path(str): 
...  def __add__(self, other): 
...    print 'add' 
...    return Path(os.path.join(str(self), other)) 
... 
>>> p = Path(r'/the/path') 
>>> p + 'thefile.txt' 
add 
>>> class Path(str): 
...  def __add__(self, other): 
...    print 'add' 
...    return Path(os.path.join(self, other)) 
... 
>>> p = Path(r'/the/path') 
>>> p + 'file.txt' 
add 
add 
# add printed twice 

solución más simple: Cambio

return Path(os.path.join(self, other)) 

a

return Path(os.path.join(str(self), other)) 

Funciona.

+1

Bueno, eso es lo que acabo de escribir en mi pregunta ... Quería saber si se trata de una implementación de error o CPython u otra cosa. Por cierto 'isinstance' devolverá True en este caso – JBernardo

+0

Sí, tienes razón. Debe tener 'string .__ class __.__ name__ == 'str'' –

+0

No, el intérprete no verificará esa cadena porque puedo cambiarla en cualquier momento ... – JBernardo