2011-10-07 22 views
5

Czy ktoś wie, dlaczego funkcja os.path.join nie działa z podklasami str?os.path.join z podklasą str

(używam Python3.2 x64 i x86 Python2.7 na Windows, a wynik jest taki sam)

To kod mam

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' 

a wynik chcę:

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

ale wyjście to \\some_file.txt bez względu na wartość self.

wiem, że mogę zrobić albo str(self) lub zapisać go jako self.path i użyć później, ale dlaczego os.join.path nie akceptuje podklasy str ani podnieść błąd (jak w przypadku korzystania z numeru lub dowolnego innego typu string)?

Odpowiedz

0

W razie wątpliwości sprawdź źródło (Python32 \ Lib \ ntpath.py). Istotne zalety:

„” „połączenie dwóch lub więcej składników o ścieżce, wstawienie«\»ile potrzeba Jeżeli którykolwiek składnik jest ścieżka bezwzględna wszystkie poprzednie elementy toru są odrzucane.,«»” (Podkreślenie)

kierunku dna funkcji join próbuje umieścić \ między dwoma kawałkami użyciu path += '\\' + b (gdzie b jest some_file.txt) - który najpierw dodaje \ i some_file.txt (które są gładkie struny), po czym dodaje, że do Path(r'c:\the\path') wywołując Path.__add__(r'c:\the\path', r'\some_file.txt'), ponownie Zadzwoń pod numer os.path.join ...

Czy zauważyłeś teraz wiodącą nazwę \ w nazwie pliku? Dlatego początkowa część ścieżki ginie.

Wywołanie os.path.join z str(self) (lub self.path) działa bo wtedy os.path.join jest tylko nazywane są raz zamiast dwukrotnie.

1

Wygląda na to, że os.path.join używa metody kompilacji w __add__, można to zweryfikować, umieszczając instrukcję drukowania w metodzie __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 

Najprostsze rozwiązanie: Zmień

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

do

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

To działa.

+1

Cóż, właśnie to właśnie napisałem w moim pytaniu ... Chciałem wiedzieć, czy to błąd, czy implementacja CPython, czy coś innego. BTW 'isinstance' zwróci True w tym przypadku – JBernardo

+0

Tak, masz rację. Musi mieć 'string .__ class __.__ name__ == 'str'' –

+0

Nie, interpreter nie sprawdzi tego ciągu, ponieważ mogę go zmienić w każdej chwili ... – JBernardo

Powiązane problemy