มีคนบอกฉันเกี่ยวกับวิธีรับไดเรกทอรีพาเรนต์ใน Python แบบข้ามแพลตฟอร์ม เช่น
C:\Program Files ---> C:\
และ
C:\ ---> C:\
หากไดเรกทอรีไม่มีไดเรกทอรีหลักจะส่งคืนไดเรกทอรีเอง คำถามอาจดูเหมือนง่าย แต่ฉันไม่สามารถขุดผ่าน Google
มีคนบอกฉันเกี่ยวกับวิธีรับไดเรกทอรีพาเรนต์ใน Python แบบข้ามแพลตฟอร์ม เช่น
C:\Program Files ---> C:\
และ
C:\ ---> C:\
หากไดเรกทอรีไม่มีไดเรกทอรีหลักจะส่งคืนไดเรกทอรีเอง คำถามอาจดูเหมือนง่าย แต่ฉันไม่สามารถขุดผ่าน Google
คำตอบ:
ใช้pathlib
โมดูล
from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent)
ลองสิ่งนี้:
import os.path
print os.path.abspath(os.path.join(yourpath, os.pardir))
ที่yourpath
อยู่ในเส้นทางที่คุณต้องการสำหรับผู้ปกครอง
os.pardir
os.path.pardir
os.pardir
และos.path.pardir
เป็นจริงที่ถูกต้อง (พวกเขาเป็นเหมือนกัน)
os.path.dirname
ให้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับว่ามีการรวมเครื่องหมายสแลชต่อท้ายในเส้นทางหรือไม่ หากคุณต้องการผลลัพธ์ที่เชื่อถือได้คุณต้องใช้os.path.join
วิธีการดังกล่าวข้างต้น
การใช้os.path.dirname
:
>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>
Caveat: os.path.dirname()
ให้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับว่ามีการต่อท้ายสแลชในเส้นทางหรือไม่ นี่อาจเป็นหรือไม่เป็นความหมายที่คุณต้องการ cf เลย @ คำตอบ kender os.path.join(yourpath, os.pardir)
โดยใช้
os.path.dirname(r'C:\Program Files')
อะไร? Python เพียงแค่ให้ไดเรกทอรีที่ไฟล์ 'Program Files' แก่คุณ ยิ่งไปกว่านั้นมันไม่จำเป็นต้องมีอยู่อีกแล้วดูเถิด: os.path.dirname(r'c:\i\like\to\eat\pie')
เอาท์พุท'c:\\i\\like\\to\\eat'
from pathlib import Path
Path('C:\Program Files').parent
# Returns a Pathlib object
import os.path
os.path.dirname('C:\Program Files')
# Returns a string
ใช้วิธีการดั้งเดิมถ้า:
คุณเป็นห่วงเกี่ยวกับข้อผิดพลาดในการสร้างรหัสที่มีอยู่หากใช้วัตถุ Pathlib (เนื่องจากวัตถุ Pathlib ไม่สามารถต่อกับสตริงได้)
Python เวอร์ชันของคุณน้อยกว่า 3.4
คุณต้องการสตริงและคุณได้รับสตริง พูดเช่นคุณมีสตริงที่แสดงถึงพา ธ ไฟล์และคุณต้องการรับพาเรนต์ไดเร็กทอรีเพื่อให้คุณสามารถวางไว้ในสตริง JSON มันจะเป็นการโง่ที่จะแปลงเป็นวัตถุ Pathlib และกลับมาอีกครั้งสำหรับสิ่งนั้น
หากไม่มีข้อใดข้อหนึ่งข้างต้นให้ใช้ Pathlib
หากคุณไม่ทราบว่า Pathlib คืออะไรโมดูล Pathlib เป็นโมดูลที่ยอดเยี่ยมที่ทำให้การทำงานกับไฟล์ง่ายขึ้นสำหรับคุณ ส่วนใหญ่หากไม่ใช่โมดูล Python ในตัวทั้งหมดที่ทำงานกับไฟล์จะยอมรับทั้งวัตถุและสตริง Pathlib ฉันได้เน้นด้านล่างตัวอย่างจากเอกสาร Pathlibที่แสดงบางสิ่งที่เรียบร้อยที่คุณสามารถทำได้กับ Pathlib
การนำทางภายในแผนผังไดเรกทอรี:
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')
การค้นหาคุณสมบัติพา ธ :
>>> q.exists()
True
>>> q.is_dir()
False
pip install pathlib2
และใช้ backport
os.sep
!
import os
p = os.path.abspath('..')
C:\Program Files
---> C:\\\
C:\
---> C:\\\
os.path.abspath(r'E:\O3M_Tests_Embedded\branches\sw_test_level_gp\test_scripts\..\..')
ผล:E:\\O3M_Tests_Embedded\\branches
/
.
โซลูชันสำรองของ @kender
import os
os.path.dirname(os.path.normpath(yourpath))
ที่yourpath
อยู่ในเส้นทางที่คุณต้องการสำหรับผู้ปกครอง
แต่วิธีการแก้ปัญหานี้ไม่สมบูรณ์แบบเพราะมันจะไม่จัดการกับกรณีที่yourpath
สตริงว่างหรือจุด
โซลูชันอื่น ๆ นี้จะจัดการกับกรณีมุมนี้ได้ดียิ่งขึ้น:
import os
os.path.normpath(os.path.join(yourpath, os.pardir))
นี่คือผลลัพธ์สำหรับทุก ๆ กรณีที่สามารถค้นหาได้ (เส้นทางเข้านั้นสัมพันธ์กัน):
os.path.dirname(os.path.normpath('a/b/')) => 'a'
os.path.normpath(os.path.join('a/b/', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/b')) => 'a'
os.path.normpath(os.path.join('a/b', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/')) => ''
os.path.normpath(os.path.join('a/', os.pardir)) => '.'
os.path.dirname(os.path.normpath('a')) => ''
os.path.normpath(os.path.join('a', os.pardir)) => '.'
os.path.dirname(os.path.normpath('.')) => ''
os.path.normpath(os.path.join('.', os.pardir)) => '..'
os.path.dirname(os.path.normpath('')) => ''
os.path.normpath(os.path.join('', os.pardir)) => '..'
os.path.dirname(os.path.normpath('..')) => ''
os.path.normpath(os.path.join('..', os.pardir)) => '../..'
เส้นทางอินพุตเป็นสัมบูรณ์ (เส้นทาง Linux):
os.path.dirname(os.path.normpath('/a/b')) => '/a'
os.path.normpath(os.path.join('/a/b', os.pardir)) => '/a'
os.path.dirname(os.path.normpath('/a')) => '/'
os.path.normpath(os.path.join('/a', os.pardir)) => '/'
os.path.dirname(os.path.normpath('/')) => '/'
os.path.normpath(os.path.join('/', os.pardir)) => '/'
os.path.split(os.path.abspath(mydir))[0]
os.path.split(os.path.abspath("this/is/a/dir/"))[0]
ผลตอบแทน'/home/daniel/this/is/a'
ตามที่คาดไว้ ฉันไม่มีกล่อง Windows ที่ใช้งานอยู่เพื่อตรวจสอบที่นั่น คุณได้สังเกตเห็นการทำงานของการตั้งค่าที่คุณรายงานไว้หรือไม่
parentdir = os.path.split(os.path.apspath(dir[:-1]))[0]
คุณสามารถทำ สิ่งนี้ - ฉันมั่นใจ - ทำงานได้เพราะหากมีเครื่องหมายทับอยู่ท้ายสุดมันจะถูกลบออก หากไม่มีเครื่องหมายทับจะยังคงใช้งานได้ (แม้ว่าส่วนสุดท้ายของเส้นทางจะยาวเพียงหนึ่งอักขระเท่านั้น) เนื่องจากเครื่องหมายทับก่อนหน้า แน่นอนว่านี้ถือว่าเส้นทางนั้นเหมาะสมและไม่พูดอะไรบางอย่าง/a//b/c///d////
(ในระบบยูนิกซ์ที่ใช้ได้) ซึ่งโดยส่วนใหญ่แล้วจะเป็น (เหมาะสม) โดยเฉพาะอย่างยิ่งเมื่อคุณทำบางสิ่งบางอย่างเช่นos.path.abspath
หรือos.path
ฟังก์ชั่นอื่น ๆ
os.path.split("a/b//c/d///")
และcd //////dev////// is equivalent to
cd / dev / `หรือcd /dev
; ทั้งหมดนี้ใช้ได้ใน linux ฉันเพิ่งมากับสิ่งนี้และมันอาจจะมีประโยชน์แม้ว่า: os.path.split(path[:tuple(ind for ind, char in enumerate(path) if char != "/" and char != "\\")[-1]])[0]
. (นี้เป็นหลักค้นหาสำหรับที่ผ่านมาไม่ใช่เฉือนและได้รับการย่อยของเส้นทางขึ้นไปถ่านนั้น.) ฉันใช้แล้ววิ่งคำสั่งดังกล่าวและได้path = "/a//b///c///d////"
'/a//b///c'
os.path.abspath(os.path.join(somepath, '..'))
สังเกต:
import posixpath
import ntpath
print ntpath.abspath(ntpath.join('C:\\', '..'))
print ntpath.abspath(ntpath.join('C:\\foo', '..'))
print posixpath.abspath(posixpath.join('/', '..'))
print posixpath.abspath(posixpath.join('/home', '..'))
import os
print"------------------------------------------------------------"
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
print("example 1: "+SITE_ROOT)
PARENT_ROOT=os.path.abspath(os.path.join(SITE_ROOT, os.pardir))
print("example 2: "+PARENT_ROOT)
GRANDPAPA_ROOT=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))
print("example 3: "+GRANDPAPA_ROOT)
print "------------------------------------------------------------"
หากคุณต้องการเพียงชื่อของโฟลเดอร์ที่เป็นผู้ปกครองทันทีของไฟล์ที่มีให้เป็นอาร์กิวเมนต์และไม่เส้นทางที่แน่นอนไปยังแฟ้มที่:
os.path.split(os.path.dirname(currentDir))[1]
เช่นที่มีcurrentDir
ค่า/home/user/path/to/myfile/file.ext
คำสั่งดังกล่าวจะกลับมา:
myfile
>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))
ตัวอย่างใน Ubuntu:
>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'
ตัวอย่างเช่นใน Windows:
>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'
ทั้งสองตัวอย่างพยายามใน Python 2.7
import os.path
os.path.abspath(os.pardir)
สมมติว่าเรามีโครงสร้างไดเรกทอรีเช่น
1]
/home/User/P/Q/R
เราต้องการเข้าถึงเส้นทางของ "P" จากไดเรกทอรี R จากนั้นเราสามารถเข้าถึงการใช้
ROOT = os.path.abspath(os.path.join("..", os.pardir));
2]
/home/User/P/Q/R
เราต้องการเข้าถึงเส้นทางของไดเรกทอรี "Q" จากไดเรกทอรี R จากนั้นเราสามารถเข้าถึงการใช้
ROOT = os.path.abspath(os.path.join(".", os.pardir));
เพียงเพิ่มบางสิ่งในคำตอบของตุง (คุณต้องใช้rstrip('/')
เพื่อให้เป็นด้านที่ปลอดภัยยิ่งขึ้นถ้าคุณอยู่ในกล่องยูนิกซ์)
>>> input = "../data/replies/"
>>> os.path.dirname(input.rstrip('/'))
'../data'
>>> input = "../data/replies"
>>> os.path.dirname(input.rstrip('/'))
'../data'
แต่ถ้าคุณไม่ใช้rstrip('/')
ให้ป้อนข้อมูลของคุณคือ
>>> input = "../data/replies/"
จะเอาท์พุท
>>> os.path.dirname(input)
'../data/replies'
ซึ่งอาจไม่ใช่สิ่งที่คุณกำลังดูอยู่ตามที่คุณต้องการทั้งสอง"../data/replies/"
และ"../data/replies"
ประพฤติแบบเดียวกัน
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_path = os.path.abspath(os.path.join(dir_path, os.pardir))
print os.path.abspath(os.path.join(os.getcwd(), os.path.pardir))
คุณสามารถใช้สิ่งนี้เพื่อรับไดเร็กทอรีพาเรนต์ของตำแหน่งปัจจุบันของไฟล์ py ของคุณ
รับพา ธ ไดเร็กทอรีพาเรนต์และสร้างไดเร็กทอรีใหม่ (ชื่อnew_dir
)
os.path.abspath('..')
os.pardir
import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.pardir, 'new_dir'))
import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.path.abspath('..'), 'new_dir'))
os.path.abspath('D:\Dir1\Dir2\..')
>>> 'D:\Dir1'
ดังนั้น..
ช่วย
import os
def parent_filedir(n):
return parent_filedir_iter(n, os.path.dirname(__file__))
def parent_filedir_iter(n, path):
n = int(n)
if n <= 1:
return path
return parent_filedir_iter(n - 1, os.path.dirname(path))
test_dir = os.path.abspath(parent_filedir(2))
คำตอบที่ให้ไว้ข้างต้นล้วนเป็นสิ่งที่สมบูรณ์แบบสำหรับการเพิ่มระดับไดเรกทอรีหนึ่งหรือสองระดับ แต่พวกเขาอาจได้รับความยุ่งยากเล็กน้อยหากต้องการสำรวจแผนผังไดเรกทอรีโดยใช้หลายระดับ (เช่น 5 หรือ 10) สิ่งนี้สามารถทำได้อย่างกระชับโดยการเข้าร่วมรายการของสิ่งN
os.pardir
ต่อos.path.join
ไปนี้ ตัวอย่าง:
import os
# Create list of ".." times 5
upup = [os.pardir]*5
# Extract list as arguments of join()
go_upup = os.path.join(*upup)
# Get abspath for current file
up_dir = os.path.abspath(os.path.join(__file__, go_upup))
os.path.dirname
เป็นฟังก์ชั่นนี้เหมือนจะซับซ้อนมากกว่าa+=5-4
a+=1
คำถามที่ร้องขอเฉพาะไดเรกทอรีหลักไม่ว่าจะมีอยู่หรือไดเรกทอรีหลักจริงสมมติว่ามีการเชื่อมโยงสัญลักษณ์เข้าทาง