วิธีรับพา ธ ไฟล์แบบสัมบูรณ์ใน Python


723

เมื่อกำหนดพา ธ เช่น"mydir/myfile.txt"ฉันจะค้นหาพา ธ สัมบูรณ์ของไฟล์เทียบกับไดเรกทอรีการทำงานปัจจุบันใน Python ได้อย่างไร เช่นใน Windows ฉันอาจท้ายด้วย:

"C:/example/cwd/mydir/myfile.txt"

2
คำถามที่คล้ายกัน: stackoverflow.com/questions/7165749/…
Raj

คำตอบ:


1055
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

ใช้งานได้หากเป็นเส้นทางที่แน่นอนอยู่แล้ว:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

29
หมายเหตุ: บนแพลตฟอร์มส่วนใหญ่นี้จะเทียบเท่ากับการเรียกฟังก์ชั่นดังต่อไปนี้:normpath() normpath(join(os.getcwd(), path))ดังนั้นถ้าmydir/myfile.txtทำไม่อยู่ภายใต้os.getcwd()เส้นทางที่แน่นอนคือไม่ได้เป็นเส้นทางที่แท้จริง
coanor

32
@coanor? โดยไม่ต้องมีรากที่ชัดเจนโดยปริยายหมายถึงเส้นทางภายในไดเรกทอรีการทำงานปัจจุบันที่เป็นอยู่จึงเทียบเท่ากับmydir/myfile.txt ./mydir/myfile.txtนั่นอาจไม่ใช่เส้นทางที่คุณตั้งใจจะป้อนข้อมูล แต่ดูเหมือนว่าการตีความเส้นทางที่ถูกต้องเท่าที่ฉันจะบอกได้ คุณสามารถทำอย่างละเอียด?
jpmc26

2
@ jpmc26 ฉันไม่ได้ปฏิบัติตาม coanor แต่ฉันจะบอกว่า (ตรงกันข้ามกับสิ่งที่ฉันสันนิษฐาน) ไม่มีการเชื่อมโยงระหว่างการโต้แย้งไปยังabspathฟังก์ชั่นและไฟล์จริง คุณสามารถให้ไฟล์ชื่อพา ธ - ที่ไม่มีอยู่ใด ๆ และไดเรกตอรีไดเรกตอรี่นั้นละเอียด - และ abspath จะแก้ไขบิตของพา ธ (รวมถึง..องค์ประกอบพาเรนต์ไดเรกทอรี " ") และส่งคืนสตริง นี่เป็นเพียงสตริงที่คำนวณจากไดเรกทอรีปัจจุบัน ความสัมพันธ์ใด ๆ กับไฟล์จริงไม่ได้ตั้งใจดูเหมือนว่า ลองos.path.abspath("/wow/junk/../blha/hooey")ดู มันได้ผล.
Mike S

2
@ MikeS ฉันไม่แน่ใจว่าทำไมมันถึงเป็นพฤติกรรมที่ไม่คาดคิด เป็นเส้นทางที่แน่นอนไม่ใช่ไฟล์หรือไดเรกทอรีแน่นอน os.path.existsหากคุณต้องการการตรวจสอบการดำรงอยู่ของโทร ในทางตรงกันข้ามระบบเช่น PowerShell ที่ยืนยันในเส้นทางที่มีอยู่ด้วยฟังก์ชั่นการแก้ปัญหาเส้นทางมาตรฐานเป็นความเจ็บปวดที่จะใช้
jpmc26

1
@ jpmc26 สมมติว่าเส้นทางเป็นเพียงสตริงที่ดูเหมือนชื่อพา ธ ไม่ชัดเจนเลยและกลับไปที่วิธีที่ฉันคิดและพูดถึงชื่อพา ธ เป็นเวลาหลายปี ฉันพูดหลาม 3 เอกสารสำหรับ abspath: "กลับมาเป็นรุ่น absolutized ปกติชื่อพา ธเส้นทาง ." ไม่ใช่ "รุ่นสตริง พา ธ " ... ชื่อพา ธ ตามที่กำหนดโดย Posix คือ "สตริงที่ใช้เพื่อระบุไฟล์" Python docs มีความชัดเจนเกี่ยวกับrelpath: "ไม่สามารถเข้าถึงระบบไฟล์เพื่อยืนยันการมีอยู่หรือลักษณะของpath" ถ้าอาร์กิวเมนต์ที่นี่เป็นที่ชัดเจนว่าทำไมเป็นที่ชัดเจนสำหรับrelpath?
Mike S

77

คุณสามารถใช้ห้องสมุด Python 3.4 pathlibใหม่ (คุณสามารถใช้เพื่อใช้งาน Python 2.6 หรือ 2.7 pip install pathlibได้) ผู้เขียนเขียนว่า : "เป้าหมายของไลบรารีนี้คือการจัดลำดับชั้นอย่างง่ายของคลาสเพื่อจัดการกับเส้นทางของระบบไฟล์และการดำเนินการทั่วไปที่ผู้ใช้ทำ

วิธีรับพา ธ สัมบูรณ์ใน Windows:

>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\\Python27\\pythonw.exe'

หรือบน UNIX:

>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'

เอกสารอยู่ที่นี่: https://docs.python.org/3/library/pathlib.html


4
มีประโยชน์มาก การใช้os.path.abspath()ทำให้ฉันมีข้อผิดพลาด: การAttributeError: 'NoneType' object has no attribute 'startswith'ใช้Path().resolve()ไม่ได้มีไฟล์พา ธ แบบเดียวกัน (Linux และ Python3.4)
NuclearPeon

23

ยังดีกว่าติดตั้งโมดูล (พบในPyPI) มันห่อos.pathฟังก์ชั่นทั้งหมดและฟังก์ชั่นอื่น ๆ ที่เกี่ยวข้องเป็นวิธีการในวัตถุที่สามารถใช้งานได้ทุกที่ใช้สตริง:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>

2
น่าเสียดายที่พวกเขาไม่เคยมีโมดูลชื่อไฟล์ที่เป็นนามธรรมใน stdlib
Torsten Marek

1
@ Torsten Marek: มันเป็นความเจ็บปวดและการละเลยมานาน
ไหล

4
พวกเขาได้ในขณะนี้สำหรับ Python pathlib3.4: ดูคำตอบของฉันในหัวข้อนี้
twasbrillig

คำตอบนี้มี yypos มันควรจะเป็นfrom path import Pathแล้วPath('mydir/myfile.txt').abspath()
frakman1

ไม่มีการพิมพ์ผิดคุณอาจใช้pathโมดูลอื่น pathโมดูลเชื่อมโยงใช้คลาสที่มีชื่อว่า
Tom

14

วันนี้คุณสามารถใช้unipathแพ็คเกจที่มีพื้นฐานมาจากpath.py: http://sluggo.scrapping.cc/python/unipath/

>>> from unipath import Path
>>> absolute_path = Path('mydir/myfile.txt').absolute()
Path('C:\\example\\cwd\\mydir\\myfile.txt')
>>> str(absolute_path)
C:\\example\\cwd\\mydir\\myfile.txt
>>>

ฉันจะแนะนำให้ใช้แพคเกจนี้ตามที่มีอินเตอร์เฟซที่สะอาดเพื่อสาธารณูปโภค os.path ทั่วไป


10

อัปเดตสำหรับ Python 3.4+ pathlibที่ตอบคำถามได้จริง:

from pathlib import Path

relative = Path("mydir/myfile.txt")
absolute = relative.absolute()  # absolute is a Path object

หากคุณต้องการสตริงชั่วคราวโปรดจำไว้ว่าคุณสามารถใช้Pathวัตถุที่มีฟังก์ชั่นที่เกี่ยวข้องทั้งหมดos.pathรวมถึงแน่นอนabspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object

9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

โปรดทราบว่าexpanduserจำเป็น (บน Unix) ในกรณีที่นิพจน์ที่กำหนดสำหรับชื่อไฟล์ (หรือไดเรกทอรี) และตำแหน่งอาจมีการนำหน้า~/(ตัวหนอนหมายถึงโฮมไดเร็กตอรี่ของผู้ใช้) และexpandvarsดูแลตัวแปรสภาพแวดล้อมอื่น ๆ (เช่น$HOME)


6

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

import sys,os

filename = sys.argv[0]

จากตรงนั้นคุณสามารถรับเส้นทางแบบเต็มของสคริปต์ด้วย:

>>> os.path.abspath(filename)
'/foo/bar/script.py'

นอกจากนี้ยังช่วยให้นำทางโฟลเดอร์ได้ง่ายขึ้นโดยต่อท้าย/..หลาย ๆ ครั้งตามที่คุณต้องการ 'ขึ้น' ในลำดับชั้นของไดเรกทอรี

ในการรับ cwd:

>>> os.path.abspath(filename+"/..")
'/foo/bar'

สำหรับพาเรนต์พา ธ :

>>> os.path.abspath(filename+"/../..")
'/foo'

โดยการรวม"/.."กับชื่อไฟล์อื่น ๆ คุณสามารถเข้าถึงไฟล์ใด ๆ ในระบบ


นี่ไม่ใช่สิ่งที่ถูกถาม พวกเขาถามเกี่ยวกับเส้นทางที่เกี่ยวข้องกับไดเรกทอรีการทำงานปัจจุบันซึ่งไม่เหมือนกับไดเรกทอรีสคริปต์แม้ว่าบางครั้งพวกเขาอาจจะมีค่าเดียวกัน
องค์ประกอบของการสร้างสรรค์

3

โมดูลosเป็นวิธีการค้นหาเส้นทาง abs

แต่เส้นทางส่วนใหญ่ใน Linux เริ่มต้นด้วย~(tilde) ซึ่งไม่ให้ผลลัพธ์ที่น่าพอใจ

เพื่อให้คุณสามารถใช้srblibสำหรับการที่

>>> import os
>>> os.path.abspath('~/hello/world')
'/home/srb/Desktop/~/hello/world'
>>> from srblib import abs_path
>>> abs_path('~/hello/world')
'/home/srb/hello/world'

ติดตั้งโดยใช้ python3 -m pip install srblib

https://pypi.org/project/srblib/


1

ฉันชอบที่จะใช้ glob

นี่คือวิธีแสดงรายการไฟล์ทุกประเภทในโฟลเดอร์ปัจจุบันของคุณ:

import glob
for x in glob.glob():
    print(x)

นี่คือวิธีการแสดงรายการทั้งหมด. (ตัวอย่าง) ไฟล์. txt ในโฟลเดอร์ปัจจุบันของคุณ:

import glob
for x in glob.glob('*.txt'):
    print(x)

นี่คือวิธีแสดงรายการไฟล์ทุกประเภทในไดเรกทอรีที่เลือก:

import glob
for x in glob.glob('C:/example/hi/hello/'):
    print(x)

หวังว่านี่จะช่วยคุณได้


2
คุณดูเหมือนจะตอบคำถามอื่น ไม่ใช่ "ฉันจะหาเส้นทางได้อย่างไร" แต่ "เส้นทางที่แน่นอน" หนึ่งสามารถใช้คำตอบที่ถูก ( os.path.abspath()) กับสิ่งที่ทางญาติglobให้สำหรับสองกรณีแรกของคุณ ...
NichtJens

1

ถ้าคุณอยู่บน mac

import os
upload_folder = os.path.abspath("static/img/users")

สิ่งนี้จะทำให้คุณมีเส้นทางเต็มรูปแบบ:

print(upload_folder)

จะแสดงเส้นทางต่อไปนี้:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user

1

ในกรณีที่มีผู้ใช้ python และ linux และค้นหาพา ธ แบบเต็มไปยังไฟล์:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.