python: รับไดเรกทอรีสองระดับขึ้นไป


89

โอเค ... ฉันไม่รู้ว่าโมดูลอยู่ที่ไหนxแต่ฉันรู้ว่าฉันต้องได้รับเส้นทางไปยังไดเร็กทอรีสองระดับขึ้นไป

มีวิธีที่สวยงามกว่านี้ไหมที่จะทำ:

import os
two_up = os.path.dirname(os.path.dirname(__file__))

ยินดีต้อนรับโซลูชั่นสำหรับทั้ง Python 2 และ 3!


1
ฉันคิดว่าโซลูชันของคุณดีมาก pathlibวิธีการแก้ปัญหาเป็นดีกว่าเล็ก ๆ น้อย ๆ และสามารถอ่านได้มากขึ้น แต่จะไม่รวมกับงูหลาม 2.7 ฉันจะบอกว่ายึดติดกับสิ่งที่คุณมีอาจจะเพิ่มความคิดเห็น
jme

บางทีอาจจะคุ้มค่าที่จะเพิ่มpip install pathlib2ตัวเลือกในการรักษาสุขภาพใน 2.7
โจนาธาน

คำตอบ:


107

คุณสามารถใช้pathlib. น่าเสียดายที่มีอยู่ใน stdlib สำหรับ Python 3.4 เท่านั้น ถ้าคุณมีรุ่นเก่าที่คุณจะต้องติดตั้งสำเนาจาก PyPI ที่นี่ pipนี้ควรจะเป็นเรื่องง่ายที่จะทำโดยใช้

from pathlib import Path

p = Path(__file__).parents[1]

print(p)
# /absolute/path/to/two/levels/up

สิ่งนี้ใช้parentsลำดับที่ให้การเข้าถึงไดเร็กทอรีพาเรนต์และเลือกไดเร็กทอรีที่ 2 ขึ้นไป

โปรดทราบว่าpในกรณีนี้จะเป็นรูปแบบของPathวัตถุโดยมีวิธีการของตนเอง หากคุณต้องการเส้นทางเป็นสตริงคุณสามารถเรียกstrใช้งานได้


นั่นเป็นคำตอบที่ดีขอบคุณและยอดเยี่ยมสำหรับ py3 สำหรับ py2 มันเป็นไปไม่ได้ที่จะดีไปกว่าความพยายามครั้งแรกของฉันในขณะที่มันสร้างและการพึ่งพาเพิ่มเติม
jramm

16
นี่ไม่ควรเป็นคำตอบที่ยอมรับเนื่องจากPathคลาสparentsขึ้นอยู่กับสถานที่ดำเนินการ หากคุณดำเนินการ__file__จากไดเร็กทอรีปัจจุบันPathคลาสจะไม่มีผู้ปกครอง ควรยอมรับคำตอบของ @ Sebi2020 หรือควรใช้วิธีการเดิมของคุณ ฉันเชื่อว่าวิธีการเดิมของคุณอ่านง่ายกว่า
Red-Tune-84

1
คุณอาจต้องทำp = Path(os.path.abspath(__file__)).parents[1]
Adam Raudonis

4
@AdamRaudonis แทนที่จะos.path.abspathใช้Path(__file__).resolve().parents[1]
Tulio Casagrande

7
ตามที่ @Kazanz กล่าวไว้โซลูชันนี้ใช้ไม่ได้เมื่อเรียกใช้งานจากเส้นทางอื่น ทางออกที่ดีที่สุดคือ: p = Path(__file__).resolve().parents[1]. ฉันยังเพิ่มเป็นคำตอบ
pythinker

48

ง่ายมาก:

นี่คือสิ่งที่คุณต้องการ:

import os.path as path

two_up =  path.abspath(path.join(__file__ ,"../.."))

10
และบางทีอาจจะใช้มากกว่าos.pardir ..
jme

sys.argv [0] ไม่ส่งคืนโมดูลที่เรียกใช้โดย python.exe หรือไม่ ดังนั้นสิ่งนี้จะไม่จำเป็นถ้าโมดูลที่ฉันสนใจถูกนำเข้าจากแพ็คเกจอื่น .. ฉันอยู่ที่นี่หรือไม่?
jramm

หากคุณต้องการใช้ในโมดูลแทนให้ใช้__file__.
Sebi2020

1
@jme คุณรู้จักระบบปฏิบัติการที่คุณได้รับไดเรกทอรีหลักที่มีสตริงอื่นที่ไม่ใช่ ".. " ???
Sebi2020

1
@ Sebi2020 ใช่โดยเฉพาะ Mac OS รุ่นเก่า นี่คือรายการ: en.wikipedia.org/wiki/Path_( การ
คำนวณ

22

ฉันจะเพิ่มสิ่งนี้เพื่อเป็นเรื่องโง่ ๆ แต่ก็เป็นเพราะมันแสดงให้ผู้มาใหม่เห็นถึงประโยชน์ที่เป็นไปได้ของฟังก์ชันนามแฝงและ / หรือการนำเข้า

เมื่อเขียนแล้วฉันคิดว่ารหัสนี้อ่านได้ง่ายกว่า (เช่นใช้เวลาในการเข้าใจความตั้งใจน้อยกว่า) มากกว่าคำตอบอื่น ๆ ในปัจจุบันและความสามารถในการอ่านคือ (โดยปกติ)

from os.path import dirname as up

two_up = up(up(__file__))

หมายเหตุ: คุณต้องการทำสิ่งนี้ก็ต่อเมื่อโมดูลของคุณมีขนาดเล็กมากหรือสอดคล้องกันตามบริบท


14

ทางออกที่ดีที่สุด (สำหรับ python> = 3.4) เมื่อเรียกใช้งานจากไดเร็กทอรีใด ๆ คือ:

from pathlib import Path
two_up = Path(__file__).resolve().parents[1]

10

สำหรับการอัพไดเร็กทอรี 2 ระดับ:

 import os.path as path
 two_up = path.abspath(path.join(os.getcwd(),"../.."))

4

โดยส่วนตัวแล้วฉันพบว่าการใช้โมดูลระบบปฏิบัติการเป็นวิธีที่ง่ายที่สุดดังที่ระบุไว้ด้านล่าง หากคุณขึ้นไปเพียงหนึ่งระดับให้แทนที่ ('../ .. ') ด้วย ('.. ')

    import os
    os.chdir('../..')

--Check:
    os.getcwd()

1
เป็นที่ยอมรับหรือไม่ในการฮาร์ดโค้ด '/' ฉันคาดว่าจะอ่าน os.chdir (os.join ('.. ', '.. '))
GreenAsJade


2

คุณสามารถใช้สิ่งนี้เป็นวิธีแก้ปัญหาทั่วไป:

import os

def getParentDir(path, level=1):
  return os.path.normpath( os.path.join(path, *([".."] * level)) )

@ JanSila: เจาะจงได้มากกว่านี้ทำไมไม่ pythonic? เพื่อให้อ่านง่ายอาจมีความคิดเห็นเพิ่มเติมว่าสิ่งนี้ทำอย่างไรใช่ - แต่ในที่สุดก็ใช้คุณสมบัติภาษา python มาตรฐานดูเช่นstackoverflow.com/questions/36901
Axel Heider

มีความหนาแน่นเล็กน้อย แต่ฉันไม่คิดว่านี่เป็นนามธรรมเกินไปและอ่านไม่ออก เป็นเพียงคำตอบทั่วไปในเวอร์ชันอื่น ๆ ที่โพสต์ไว้ที่นี่ ฉันต้องการวิธีไลบรารีมาตรฐานในการทำสิ่งต่างๆโดยไม่จำเป็นต้องใช้ฟังก์ชัน
ryanjdillon

1

การใช้งานข้ามแพลตฟอร์มเพิ่มเติม ได้แก่ :

import pathlib
two_up = (pathlib.Path(__file__) / ".." / "..").resolve()

ใช้parentไม่ได้รับการสนับสนุนบน Windows ยังต้องเพิ่ม.resolve()ไปที่:

ทำให้เส้นทางเป็นค่าสัมบูรณ์แก้ไขลิงก์สัญลักษณ์ทั้งหมดระหว่างทางและทำให้เป็นปกติ (เช่นเปลี่ยนเครื่องหมายทับเป็นแบ็กสแลชใน Windows)


2
คุณมีแหล่งที่parentไม่ทำงานบน Windows หรือไม่? ดูเหมือนว่าจะได้รับการแก้ไขในบางครั้งเนื่องจากคุณเขียนความคิดเห็นนี้ ใช้งานได้ดีสำหรับฉันโดยใช้ Python 3.7.2 บน Windows 10
Nathan

ฉันสามารถparentทำงานบน windows 10 ด้วย python 3.6.5 คุณกำลังพูดถึง @Zhukovgeen เวอร์ชันไหน
ggulgulia

@ggulgulia ฉันเชื่อว่ามันเป็น 3.7
zhukovgreen

1

สมมติว่าคุณต้องการเข้าถึงโฟลเดอร์ชื่อ xzy สองโฟลเดอร์ขึ้นไฟล์ python ของคุณ สิ่งนี้ใช้ได้กับฉันและเป็นอิสระจากแพลตฟอร์ม

".././xyz"



-1

ฉันยังไม่เห็นคำตอบที่ใช้ได้สำหรับ 2.7 ซึ่งไม่จำเป็นต้องติดตั้งการอ้างอิงเพิ่มเติมและเริ่มจากไดเร็กทอรีของไฟล์ มันไม่ดีเท่าโซลูชันแบบบรรทัดเดียว แต่ไม่มีอะไรผิดปกติกับการใช้ยูทิลิตี้มาตรฐาน

import os

grandparent_dir = os.path.abspath(  # Convert into absolute path string
    os.path.join(  # Current file's grandparent directory
        os.path.join(  # Current file's parent directory
            os.path.dirname(  # Current file's directory
                os.path.abspath(__file__)  # Current file path
            ),
            os.pardir
        ),
        os.pardir
    )
)

print grandparent_dir

และเพื่อพิสูจน์ว่ามันใช้งานได้ที่นี่ฉันเริ่มต้น~/Documents/notesเพียงเพื่อที่ฉันจะแสดงไดเร็กทอรีปัจจุบันไม่ส่งผลต่อผลลัพธ์ ฉันวางไฟล์ที่grandpa.pyมีสคริปต์นั้นไว้ในโฟลเดอร์ชื่อ "scripts" มันจะรวบรวมข้อมูลไปยัง dir Documents จากนั้นไปยังผู้ใช้ dir บน Mac

(testing)AlanSE-OSX:notes AlanSE$ echo ~/Documents/scripts/grandpa.py 
/Users/alancoding/Documents/scripts/grandpa.py
(testing)AlanSE-OSX:notes AlanSE$ python2.7 ~/Documents/scripts/grandpa.py 
/Users/alancoding

นี่คือการคาดการณ์ที่ชัดเจนของคำตอบสำหรับผบ . ผู้ปกครอง ดีกว่าที่จะใช้โซลูชันทั่วไปมากกว่าโซลูชันที่ดีน้อยในจำนวนบรรทัดน้อย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.