아래 코드는 디버그 할 때 명령이 전체 경로를 저장하지 않고 마지막 항목 만 저장하지 않습니다.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
이것을 테스트 할 때 /new_sandbox/
코드 의 일부만 저장합니다 .
아래 코드는 디버그 할 때 명령이 전체 경로를 저장하지 않고 마지막 항목 만 저장하지 않습니다.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
이것을 테스트 할 때 /new_sandbox/
코드 의 일부만 저장합니다 .
답변:
후자의 문자열은 슬래시로 시작해서는 안됩니다. 슬래시로 시작하면 "절대 경로"로 간주되며 그 이전의 모든 항목은 삭제됩니다.
파이썬 문서os.path.join
인용 :
구성 요소가 절대 경로 인 경우 이전의 모든 구성 요소가 버리고 절대 경로 구성 요소에서 결합이 계속됩니다.
Windows에서 드라이브 문자와 관련된 동작은 이전 Python 버전과 비교하여 변경된 것으로 보입니다.
Windows에서 절대 경로 구성 요소 (예 :)
r'\foo'
가 발생 하면 드라이브 문자가 재설정되지 않습니다 . 구성 요소에 드라이브 문자가 포함되어 있으면 이전의 모든 구성 요소가 버리고 드라이브 문자가 재설정됩니다. 각 드라이브os.path.join("c:", "foo")
에 대한 현재 디렉토리가 있으므로 ,가 아닌 드라이브C:
(c:foo
) 의 현재 디렉토리에 상대적인 경로를 나타냅니다c:\foo
.
os.path.normpath
목표를 달성하는 데 사용할 수 있습니다 .
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
또는 이와 유사한 것).
그것은 좋지 않을 수도 있지만 이것이 절대 경로 행동의 동기라고 생각합니다.
의 콤보 시도 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
두 번째 문자열과 다음 문자열에서 string을 제거하여 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"
... 나는 그 의도 된 결과 의심.