ос.путь.вступать с ул. подкласс
Кто-нибудь знает, почему функция os.path.join
не работает с подклассами str
?
(я использую Python3. 2 x64 и Python2. 7 x86 на Windows, и результат тот же)
Это код, который у меня есть
class Path(str):
def __add__(self, other):
return Path(os.path.join(self, other))
p = Path(r'C:thepath')
d = p + 'some_file.txt'
И результат, который я хочу:
'C:\the\path\some_file.txt'
Но выход будет \some_file.txt
независимо от значения self
.
Я знаю, что могу сделать либо str(self)
, либо сохранить его как self.path
и использовать позже, но почему os.join.path
не принимает подкласс str и не вызывает ошибку (например, когда вы используете число или любой нестроковый тип)?
2 ответа:
Если вы сомневаетесь, проверьте источник (Python32\Lib\ntpath.py). соответствующие биты:
"""соедините два или более компонента pathname, вставляя" \ " по мере необходимости. Если какой-либо компонент является абсолютным путем, все предыдущие компоненты пути будут отброшены."" " (курсив добавлен)
В нижней части функции
join
пытается поместить\
между двумя частями с помощьюpath += '\\' + b
(гдеb
- этоsome_file.txt
), который сначала добавляет\
иsome_file.txt
(которые являются простыми строками), затем добавляет Это кPath(r'c:\the\path')
, вызываяPath.__add__(r'c:\the\path', r'\some_file.txt')
, который будет снова вызыватьos.path.join
...Вы обратили внимание на ведущую
\
теперь на имени файла? Вот почему начальная часть пути теряется.Вызов
os.path.join
с помощьюstr(self)
(илиself.path
) работает, потому что тогдаos.path.join
вызывается только один раз, а не дважды.
Похоже, что
os.path.join
использует метод build in__add__
, Это можно проверить, поместив оператор print в метод__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
Самое простое решение: Изменение
return Path(os.path.join(self, other))
To
return Path(os.path.join(str(self), other))
Это работает.