Waarom werkt os.path.join() in dit geval niet?

De onderstaande code wordt niet toegevoegd, bij debuggen slaat de opdracht niet het hele pad op, maar alleen de laatste invoer.

os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')

Als ik dit test, slaat het alleen het /new_sandbox/deel van de code op.


Antwoord 1, autoriteit 100%

De laatste strings mogen niet beginnen met een schuine streep. Als ze met een schuine streep beginnen, worden ze beschouwd als een ‘absoluut pad’ en wordt alles ervoor weggegooid.

Citeer de Python-documenten voor os.path.join:

Als een component een absoluut pad is, worden alle voorgaande componenten weggegooid en gaat het samenvoegen verder vanaf de absolute padcomponent.

Opmerking over Windows, het gedrag met betrekking tot stationsletters, dat lijkt te zijn veranderd in vergelijking met eerdere Python-versies:

In Windows wordt de stationsletter niet opnieuw ingesteld wanneer een absoluut padcomponent (bijv. r'\foo') wordt aangetroffen. Als een component een stationsletter bevat, worden alle voorgaande componenten weggegooid en wordt de stationsletter gereset. Merk op dat aangezien er een huidige map is voor elke schijf, os.path.join("c:", "foo")een pad vertegenwoordigt dat relatief is aan de huidige map op schijf C:(c:foo), niet c:\foo.


Antwoord 2, autoriteit 33%

Het idee van os.path.join()is om je programma platformonafhankelijk te maken (linux/windows/etc).

Zelfs één schuine streep verpest het.

Dus het heeft alleen zin als het wordt gebruikt met een soort referentiepunt zoals
os.environ['HOME']of os.path.dirname(__file__).


3, Autoriteit 17%

os.path.join()kan worden gebruikt in combinatie met os.path.sepom een ​​absoluut te maken in plaats van een relatief pad.

os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')

4, Autoriteit 6%

Gebruik geen slashes aan het begin van padcomponenten, behalve bij het verwijzen naar de hoofddirectory:

os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')

Zie ook: http://docs.python.org /Library/os.path.html#os.path.join


5, Autoriteit 3%

Het is omdat uw '/new_sandbox/'begint met een /en dus wordt verondersteld te zijn ten opzichte van de hoofdmap. Verwijder de toonaangevende /.


6, Autoriteit 2%

Probeer combo van split("/")en *voor snaren met bestaande joins.

import os
home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'
os.path.join(*home.split("/"), todaystr, *new.split("/"))

Hoe het werkt …

split("/")Draait het bestaande pad naar de lijst: ['', 'home', 'build', 'test', 'sandboxes', '']

*VOOR DE LIJST Breekt elk item met de eigen parameter


7, Autoriteit 2%

Gebruik het als zodanig om uw functie meer draagbaar te maken:

os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')

of

os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')

8

Probeer met new_sandboxalleen

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox')

9

Doe het als dit, zonder ook de extra schuine strepen

root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")

10

Merk op dat een soortgelijk probleem je kan bijten als je os.path.join()gebruikt om een extensie op te nemen die al een punt bevat, wat automatisch gebeurt als je os.path.splitext(). In dit voorbeeld:

components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)

Hoewel de extension.jpgis, krijg je uiteindelijk een map met de naam “foobar” in plaats van een bestand met de naam “foobar.jpg”. Om dit te voorkomen moet je de extensie apart toevoegen:

return os.path.join("avatars", instance.username, prefix) + extension

Antwoord 11

je kunt stripde '/':

>>> os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/'.strip('/'))
'/home/build/test/sandboxes/04122019/new_sandbox'

Antwoord 12

Ik raad aan om van de tweede en de volgende strings de string os.path.septe verwijderen, zodat ze niet als absolute paden kunnen worden geïnterpreteerd:

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)

Antwoord 13

os.path.join("a", *"/b".split(os.sep))
'a/b'

een volledigere versie:

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")

Other episodes