ос.путь.вступать с ул. подкласс
Кто-нибудь знает, почему функция 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))Это работает.