ฉันไม่สามารถรับกระบวนการเปิดไดเร็กทอรีใน Windows ได้อย่างถูกต้องเนื่องจากการสแลช

ฉันต้องใช้กระบวนการย่อย เปิดเพื่อเปิดหน้าต่าง explorer (ใน Windows เท่านั้น) ด้วยเส้นทาง แต่เส้นทางที่ฉันใช้มีเครื่องหมายทับและไม่ได้ผล เพียงเปิดหน้าต่าง PC explorer ทั่วไปเท่านั้น หากฉันแทนที่ด้วยแบ็กสแลชด้วยตนเองมันก็ใช้ได้ดี แต่ฉันต้องการให้สิ่งนี้เกิดขึ้นกับเส้นทางตัวแปร

ฉันได้ลองใช้ os.path.dirname เพื่อพยายาม "ทำให้ปกติ" เส้นทาง แต่ก็ไม่ได้ผลเช่นกัน IOW รหัสนี้ให้เฉพาะหน้าต่าง PC explorer ทั่วไปเท่านั้น:

myRoot = "D:/SomePath/Somefile"
subprocess.Popen(r'explorer /select, myRoot')

หรือแม้กระทั่ง:

myRoot = "D:/SomePath/Somefile"
subprocess.Popen(r'explorer /select, os.path.abspath(myRoot)')

แต่สิ่งนี้ได้ผล:

myRoot = "D:\SomePath\Somefile"
subprocess.Popen(r'explorer /select, myRoot')

ฉันได้ลองแทนที่สตริงสแลชเหล่านั้นด้วยตนเองแล้ว แต่ฉันไม่สามารถรับมันได้ไม่ว่าจะลองไปหลายวิธีแล้ว (เห็นได้ชัดว่ากำลังทำอะไรผิด) มีเบาะแสอะไรบ้าง? (ฉันต้องการสิ่งนี้เพื่อทำงานใน Windows เท่านั้น และไม่มีทางที่ฉันจะได้รับเครื่องหมายทับไม่ให้เข้ามาเพราะฉันอ่านจากไฟล์ที่สร้างด้วยโปรแกรมภายนอก)

ฉันขอขอบคุณความช่วยเหลือที่ผู้คนพยายามมอบให้ แต่ให้ฉันลองอธิบายให้กระจ่างกว่านี้ก่อน บรรทัดของเส้นทางมาจากไฟล์ภายนอกที่ฉันไม่สามารถควบคุมได้ ดังนั้นจึงดูเหมือนตัวอย่างที่มีเครื่องหมายทับเสมอ ซึ่งใช้ไม่ได้กับการเปิดกระบวนการย่อย explorer ไม่ว่าฉันจะลองด้วยวิธีใดก็ตาม (รวมถึงตัวอย่างที่ให้ไว้ด้านล่าง)

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


person Mike Kelley    schedule 03.05.2019    source แหล่งที่มา
comment
คุณหมายถึงอะไรโดยฉันได้ลองแทนที่สตริงสแลชเหล่านั้นด้วยตนเองแล้ว แต่ฉันไม่สามารถรับได้ไม่ว่าฉันจะลองหลายวิธีก็ตาม ในตัวอย่างที่สามของคุณ ด้วยเครื่องหมายทับด้านหลัง คุณบอกว่ามันได้ผล   -  person Niels Henkens    schedule 03.05.2019
comment
วิธีที่ 2 ได้ผล   -  person Smart Manoj    schedule 03.05.2019
comment
ไม่ การแทนที่เหล่านั้นไม่ได้ผลเลย อันที่สอง (ด้วย .replace) พาฉันไปที่ไดเร็กทอรี My Documents (แปลกเพราะเส้นทางอยู่บนไดรฟ์ D: ดังนั้นจึงไม่มี C: อยู่ในนั้นเลย) และสิ่งที่ฉันพูดเมื่อไม่มีงานทดแทนฉันหมายถึงไม่มีงานทดแทนที่คำนวณได้ ฉันสามารถเขียนเส้นทางด้วยเครื่องหมายทับที่ถูกต้องได้ด้วยตนเอง แต่ไม่ว่าฉันจะพยายามแทนที่เครื่องหมายทับเหล่านั้นโดยทางโปรแกรมอย่างไร มันก็ไม่ได้ผล - มันจะไม่แทนที่หรือส่งคืนเส้นทางที่ถูกต้อง   -  person Mike Kelley    schedule 03.05.2019
comment
ตกลง!!!! ความสำเร็จ -- ขอบคุณ SmartManoj! นั่นใช้งานได้ (ไม่แน่ใจว่าจะพูดอย่างไรว่านี่เป็นคำตอบเมื่อมันถูกฝังอยู่ที่นี่ แต่ฉันคิดว่าการใช้เครื่องหมายปีกกาเป็นกุญแจสำคัญ) บางทีคุณอาจโพสต์มันเป็นคำตอบที่ฉันสามารถโหวตได้?   -  person Mike Kelley    schedule 03.05.2019


คำตอบ (2)


ค่อนข้างแน่ใจว่านี่ไม่เกี่ยวข้องกับ "เครื่องหมายสแลช" แต่เกิดจากความสับสนอื่น ๆ เกี่ยวกับวิธีการทำงานของ Python และวิธีที่อาร์กิวเมนต์คำสั่งได้รับจากกระบวนการหนึ่งไปยังอีกกระบวนการหนึ่ง

myRoot = "D:/SomePath/Somefile"
subprocess.Popen(rf'explorer /select, {os.path.abspath(myRoot)}')

ใช้งานได้ เนื่องจากตัวแปร Python ได้รับการขยายเข้าไปในสตริงที่ส่งผ่านไปยัง Popen ซึ่งเทียบเท่ากับ:

cmdline = rf'explorer /select, {os.path.abspath(myRoot)}'
subprocess.Popen(cmdline)

ซึ่งเทียบเท่ากับ:

cmdline = 'explorer /select, {root}'.format(
    root=os.path.abspath(myRoot))
subprocess.Popen(cmdline)

คำนำหน้า f ของสตริงเรียกว่า "f-string" (แบบสั้น สำหรับ ตัวอักษรสตริงที่จัดรูปแบบ)

หากคุณ print(cmdline) คุณจะเห็นว่ามันถูกขยายเป็น: "explorer /select, D:/SomePath/Somefile" และด้วยเหตุนี้เส้นทางจึงสามารถเข้าสู่กระบวนการ MS Explorer ได้

เมื่อคุณใช้งาน Popen(r'explorer /select, myRoot') ตัวแปร myRoot จะไม่ถูกขยาย ดังนั้น Explorer จึงเห็นเพียงข้อความ "myRoot" ซึ่งมีแนวโน้มว่าจะถูกเพิกเฉย

ทางเลือกที่แนะนำคือส่ง list ถึง Popen ซึ่งแต่ละองค์ประกอบเป็นอาร์กิวเมนต์บรรทัดคำสั่งแยกกัน ตัวอย่างเช่น:

Popen(['explorer', '/select', myRoot])

ดูเหมือนว่าคุณกำลังพยายามทำแต่ทำไม่ถูก

ปัญหาอื่น ๆ ที่คุณดูเหมือนจะประสบปัญหาคือ "ลำดับการหลีก" และสตริง เมื่อคุณเขียนโค้ด แบ็กสแลชจะเขียนเป็น '\\' แต่หลังจากแยกวิเคราะห์แล้ว นี่เป็นเพียงอักขระตัวเดียวเท่านั้น ตัวอย่างเช่น ด้วย:

myRoot = "D:\\SomePath\\Somefile"
print(myRoot)

จะพิมพ์ออกมา: D:\SomePath\Somefile ตัวแปรนี้ควรทำงานได้ดีกับการเรียก Popen ข้างต้น

คำนำหน้า r ปิดใช้งานการจัดการ Escape นี้ และได้รับการออกแบบสำหรับ "นิพจน์ทั่วไป" (หรือ "regexp" โปรดดูที่ re โมดูล Python) มีบทความมากมายเกี่ยวกับเรื่องนี้ หวังว่าบางสิ่งที่ฉันเขียนจะมีคีย์เวิร์ดบางส่วนที่ Google เข้าใจ

person Sam Mason    schedule 03.05.2019
comment
ขอบคุณ นั่นอธิบายได้มาก (และพาฉันไปในที่ที่ฉันอยากไป) ฉันโหวตแล้ว แต่มันบอกว่าหากมีตัวแทนน้อยกว่า 15 คน มันจะไม่แสดง/นับ แต่ฉันมีตัวแทน 15 คน เลยไม่รู้ว่าทำไมมันถึงไม่ได้ผล) - person Mike Kelley; 04.05.2019

ใช้โมดูล pathlib

from pathlib import Path
myRoot = Path("D:/path/to/wherever")

สิ่งนี้ใช้ได้กับ subprocess เช่นกัน

person isaactfa    schedule 03.05.2019