Наведений нижче код не приєднається, коли налагоджена команда не зберігає весь шлях, а лише останній запис.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
Коли я тестую це, він зберігає лише /new_sandbox/частину коду.
Наведений нижче код не приєднається, коли налагоджена команда не зберігає весь шлях, а лише останній запис.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
Коли я тестую це, він зберігає лише /new_sandbox/частину коду.
Відповіді:
Останні рядки не повинні починатися з косої риски. Якщо вони починають з косою рискою, то вони вважаються "абсолютною стежкою", і все перед ними відкидається.
Цитуючи документи Python дляos.path.join :
Якщо компонент є абсолютним шляхом, всі попередні компоненти викидаються і з'єднання триває з компонента абсолютного шляху.
Зауважте, що в Windows поведінка стосовно букв диска, яка, здається, змінилася порівняно з попередніми версіями Python:
У Windows букву диска не скидають, коли
r'\foo'зустрічається абсолютний компонент шляху (наприклад, ). Якщо компонент містить літеру диска, всі попередні компоненти викидаються, а літера диска скидається. Зауважте, що оскільки існує поточний каталог для кожного диска,os.path.join("c:", "foo")являє собою шлях відносно поточного каталогу на дискуC:(c:foo), а неc:\foo.
os.path.normpathдля досягнення цієї мети.
Ідея os.path.join()полягає в тому, щоб зробити вашу програму крос-платформою (linux / windows / тощо).
Навіть одна косою рискою її розорить.
Отже, це має сенс лише при використанні з якоюсь точкою відліку, як-от
os.environ['HOME']або os.path.dirname(__file__).
os.path.join()може використовуватися спільно з os.path.sepдля створення абсолютного, а не відносного шляху.
os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')
os.path.sepяк першого елемента для побудови абсолютного шляху краще, ніж будь-яка інша відповідь тут! Весь сенс використання, os.pathа не основних методів str, полягає у тому, щоб уникнути написання /. Розміщення кожного підкаталогу як нового аргументу та видалення всіх косої риски також чудово. Напевно, це було б хорошою ідеєю, щоб переконатися в тому, що чек todaystrне починається з косої риски! ;)
Не використовуйте прямі косої риски на початку компонентів шляху, за винятком випадків переходу до кореневого каталогу:
os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')
дивіться також: http://docs.python.org/library/os.path.html#os.path.join
Щоб зрозуміти, чому це дивне поведінка не зовсім страшне, розгляньте програму, яка приймає ім'я файлу конфігурації як аргумент:
config_root = "/etc/myapp.conf/"
file_name = os.path.join(config_root, sys.argv[1])
Якщо заявка виконана за допомогою:
$ myapp foo.conf
Буде використаний конфігураційний файл /etc/myapp.conf/foo.conf.
Але подумайте, що станеться, якщо додаток викликається за допомогою:
$ myapp /some/path/bar.conf
Потім myapp слід скористатися конфігураційним файлом на /some/path/bar.conf(а не /etc/myapp.conf/some/path/bar.confчи подібний).
Це може бути не чудово, але я вважаю, що це мотивація абсолютної поведінки на шляху.
Щоб зробити вашу функцію більш портативною, використовуйте її як таку:
os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')
або
os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')
Спробуйте комбінувати split("/")і *для рядків із наявними приєднаннями.
import os
home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'
os.path.join(*home.split("/"), todaystr, *new.split("/"))
Як це працює...
split("/") перетворює існуючий шлях у список: ['', 'home', 'build', 'test', 'sandboxes', '']
* перед списком розбиває кожен елемент списку власний параметр
Зауважте, що аналогічна проблема може вас перекусити, якщо ви os.path.join()включите розширення, яке вже містить крапку, що автоматично відбувається під час використання os.path.splitext(). У цьому прикладі:
components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)
Незважаючи на те, що extensionви, можливо, у .jpgвас з'явиться папка під назвою "foobar", а не файл під назвою "foobar.jpg". Щоб цього не допустити, потрібно додати розширення окремо:
return os.path.join("avatars", instance.username, prefix) + extension
Я рекомендую зняти рядок із другого та наступних рядків os.path.sep, не даючи інтерпретувати їх як абсолютні шляхи:
first_path_str = '/home/build/test/sandboxes/'
original_other_path_to_append_ls = [todaystr, '/new_sandbox/']
other_path_to_append_ls = [
i_path.strip(os.path.sep) for i_path in original_other_path_to_append_ls
]
output_path = os.path.join(first_path_str, *other_path_to_append_ls)
os.path.join("a", *"/b".split(os.sep))
'a/b'
більш повна версія:
import os
def join (p, f, sep = os.sep):
f = os.path.normpath(f)
if p == "":
return (f);
else:
p = os.path.normpath(p)
return (os.path.join(p, *f.split(os.sep)))
def test (p, f, sep = os.sep):
print("os.path.join({}, {}) => {}".format(p, f, os.path.join(p, f)))
print(" join({}, {}) => {}".format(p, f, join(p, f, sep)))
if __name__ == "__main__":
# /a/b/c for all
test("\\a\\b", "\\c", "\\") # optionally pass in the sep you are using locally
test("/a/b", "/c", "/")
test("/a/b", "c")
test("/a/b/", "c")
test("", "/c")
test("", "c")
"\"? Тоді стає ваш перший приклад os.path.join("a", *"/b".split("\\")), який дає результат "/b"... Я сумніваюся, що це задуманий результат.