Aşağıdaki kod birleştirilmez, hata ayıklandığında komut tüm yolu değil, yalnızca son girişi saklar.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
Bunu test ettiğimde sadece /new_sandbox/
kodun bir kısmını saklar .
Aşağıdaki kod birleştirilmez, hata ayıklandığında komut tüm yolu değil, yalnızca son girişi saklar.
os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
Bunu test ettiğimde sadece /new_sandbox/
kodun bir kısmını saklar .
Yanıtlar:
Sonraki dizeler eğik çizgi ile başlamamalıdır. Bir eğik çizgi ile başlarlarsa, o zaman "mutlak yol" olarak kabul edilirler ve onlardan önceki her şey atılır.
Python belgelerindenos.path.join
alıntı yapmak :
Bir bileşen mutlak bir yolsa, önceki tüm bileşenler atılır ve birleştirme mutlak yol bileşeninden devam eder.
Windows'ta, önceki Python sürümlerine kıyasla değişmiş gibi görünen sürücü harfleriyle ilgili davranışı not edin:
Windows'ta, mutlak bir yol bileşeniyle (örn
r'\foo'
.) Karşılaşıldığında sürücü harfi sıfırlanmaz . Bir bileşen bir sürücü harfi içeriyorsa, önceki tüm bileşenler atılır ve sürücü harfi sıfırlanır. Her sürücüos.path.join("c:", "foo")
için geçerli bir dizin bulunduğundan, sürücüdekiC:
(c:foo
) geçerli dizine göre bir yolu temsil ettiğine dikkat edinc:\foo
.
os.path.normpath
amaca ulaşmak için kullanabilirsiniz .
Ana fikri os.path.join()
programınızı çapraz platform haline getirmektir (linux / windows / etc).
Bir eğik çizgi bile onu mahveder.
Bu yüzden os.environ['HOME']
veya gibi bir referans noktası ile kullanıldığında mantıklıdır
os.path.dirname(__file__)
.
os.path.join()
os.path.sep
göreli yol yerine mutlak yol oluşturmak için ile birlikte kullanılabilir .
os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')
os.path.sep
Mutlak bir yol oluşturmak için ilk eleman olarak kullanılması, burada diğer tüm cevaplardan daha iyidir! os.path
Temel str yöntemlerinden ziyade tüm kullanım noktası yazmamaktır /
. Her alt dizini yeni bir argüman olarak koymak ve tüm eğik çizgileri kaldırmak da harika. todaystr
Eğik çizgi ile başlamayan bir çekten emin olmak iyi bir fikir olabilir ! ;)
Kök dizine başvurma dışında, yol bileşenlerinin başında eğik çizgi kullanmayın:
os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')
ayrıca bkz: http://docs.python.org/library/os.path.html#os.path.join
Bu şaşırtıcı davranışın neden tamamen korkunç olmadığını anlamaya yardımcı olması için , yapılandırma dosyası adını bağımsız değişken olarak kabul eden bir uygulamayı düşünün:
config_root = "/etc/myapp.conf/"
file_name = os.path.join(config_root, sys.argv[1])
Uygulama şununla yürütülürse:
$ myapp foo.conf
Yapılandırma dosyası /etc/myapp.conf/foo.conf
kullanılacaktır.
Ancak uygulama ile çağrılırsa ne olacağını düşünün:
$ myapp /some/path/bar.conf
Sonra myapp
gerektiğini de yapılandırma dosyasını kullanmak /some/path/bar.conf
(ve /etc/myapp.conf/some/path/bar.conf
veya benzeri).
Harika olmayabilir, ama bunun mutlak yol davranışı için motivasyon olduğuna inanıyorum.
İşlevinizi daha taşınabilir hale getirmek için aşağıdaki gibi kullanın:
os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')
veya
os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')
Varolan birleştirmeler içeren dizeleri split("/")
ve *
dizelerini birleştirmeyi deneyin .
import os
home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'
os.path.join(*home.split("/"), todaystr, *new.split("/"))
Nasıl çalışır...
split("/")
mevcut yolu listeye dönüştürür: ['', 'home', 'build', 'test', 'sandboxes', '']
*
listenin önündeki listedeki her öğeyi kendi parametresi olarak ayırır
ekstra eğik çizgiler olmadan bunu böyle yap
root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")
os.path.join()
Zaten nokta içeren bir uzantı eklemek için kullandığınızda benzer bir sorunun sizi ısıtabileceğini unutmayın ; bu, kullandığınızda otomatik olarak gerçekleşir os.path.splitext()
. Bu örnekte:
components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)
Olsa extension
olabileceğini .jpg
siz "filanca" yerine "foobar.jpg" adlı bir dosya adında bir klasör ile bitirmek. Bunu önlemek için uzantıyı ayrıca eklemeniz gerekir:
return os.path.join("avatars", instance.username, prefix) + extension
Ben os.path.sep
mutlak yollar olarak yorumlanmasını önleyerek , dizeyi ikinci ve aşağıdaki dizeleri şerit tavsiye ederim :
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'
daha dolgun bir sürüm:
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")
"\"
? Sonra ilk örneğiniz olur os.path.join("a", *"/b".split("\\"))
, bu da "/b"
sonuç verir ... Kuşkusuz amaçlanan sonuç budur.