pythonw.exe หรือ python.exe?


157

เรื่องสั้นสั้น ๆ : pythonw.exeไม่ทำอะไรเลยไม่python.exeยอมรับอะไร (ฉันควรใช้อันไหนดี)

test.py:

print "a"

หน้าต่าง CMD:

C:\path>pythonw.exe test.py
<BLANK LINE>
C:\path>

C:\path>python.exe test.py
  File "C:\path\test.py", line 7
    print "a"
            ^
SyntaxError: invalid syntax

C:\path>

โปรดบอกฉันว่าฉันทำอะไรผิดอย่างร้ายแรง


14
น่าเสียดายที่นี่เป็นการผสมผสานระหว่างสองด้านของ python กับ pythonw (โดยทั่วไปคือด้านที่น่าสนใจมากขึ้น) และการเปลี่ยนแปลงทางไวยากรณ์พื้นฐานจาก python2 เป็น python3 การวิจารณ์ของ OP ไม่มีที่ไม่สามารถทราบล่วงหน้า แต่อย่างไรก็ตามมัน taints ค่าของคำถามนี้เป็นไปสู่ทรัพยากรเกี่ยวกับงูหลามW
mnagel

คำตอบ:


170

หากคุณไม่ต้องการให้หน้าต่างเทอร์มินัลปรากฏขึ้นเมื่อคุณรันโปรแกรมให้ใช้pythonw.exe;
มิฉะนั้นให้ใช้python.exe

เกี่ยวกับข้อผิดพลาดทางไวยากรณ์: print ตอนนี้เป็นฟังก์ชันใน 3.x
ใช้แทน:

print("a")

283

เพื่อสรุปและเติมเต็มคำตอบที่มีอยู่:

  • python.exeเป็นคอนโซล (Terminal) แอพลิเคชันสำหรับการเปิดตัวสคริปต์ CLI ชนิด

    • เว้นแต่จะวิ่งออกจากหน้าต่างคอนโซลที่มีอยู่เปิดหน้าต่างคอนโซลใหม่python.exe
    • ลำธารมาตรฐาน sys.stdin , sys.stdoutและsys.stderrมีการเชื่อมต่อกับหน้าต่างคอนโซล
    • การดำเนินการเป็นแบบซิงโครนัสเมื่อเรียกใช้จากcmd.exeหน้าต่างคอนโซลหรือ PowerShell: ดูความคิดเห็นที่ 1 ของeryksunด้านล่าง

      • หากหน้าต่างคอนโซลใหม่ถูกสร้างขึ้นหน้าต่างจะยังคงเปิดอยู่จนกว่าสคริปต์จะสิ้นสุด
      • เมื่อเรียกใช้จากหน้าต่างคอนโซลที่มีอยู่พรอมต์จะถูกบล็อกจนกว่าสคริปต์จะสิ้นสุด
  • pythonw.exeเป็น app GUI สำหรับการเปิดตัว GUI / ไม่มี UI-at-สคริปต์ทั้งหมด

    • ไม่มีหน้าต่างคอนโซลเปิดอยู่
    • การดำเนินการแบบอะซิงโครนัส :
      • เมื่อเรียกจากหน้าต่างคอนโซลสคริปต์ที่เป็นเพียงการเปิดตัวและผลตอบแทนที่พรอมต์ได้ทันทีไม่ว่าจะเป็นสคริปต์ที่ยังคงทำงานอยู่หรือไม่
    • มาตรฐานลำธาร sys.stdin , sys.stdoutและsys.stderrมีไม่สามารถใช้ได้ไม่สามารถใช้ได้
      • ข้อควรระวัง : ถ้าคุณใช้ขั้นตอนพิเศษนี้มีผลข้างเคียงที่อาจเกิดขึ้นที่ไม่คาดคิด :
        • ข้อยกเว้นที่ไม่สามารถจัดการทำให้เกิดสคริปต์เพื่อยกเลิกการอย่างเงียบ ๆอย่างเงียบ ๆ
        • ใน Python 2.x การพยายามใช้งานprint()สามารถทำให้เกิดเหตุการณ์นั้นขึ้น (ใน 3.x print()เพียง แต่ไม่มีผลใด ๆ )
        • เพื่อป้องกันสิ่งนั้นจากในสคริปต์ของคุณและเพื่อเรียนรู้เพิ่มเติมดูคำตอบของฉัน
        • เฉพาะกิจคุณสามารถใช้การเปลี่ยนเส้นทางผลลัพธ์ : ขอบคุณ @handle
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (จาก PowerShell:
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt) ที่ stdout จับและเอาท์พุท stderr ในไฟล์
          หากคุณมั่นใจว่าการใช้print()เป็นเพียงเหตุผลเดียวที่สคริปต์ของคุณไม่ทำงานอย่างเงียบ ๆpythonw.exeและคุณไม่สนใจเอาต์พุต stdout ให้ใช้คำสั่ง @ handle จากความคิดเห็น:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Caveat : เทคนิคการเปลี่ยนเส้นทางผลลัพธ์นี้ไม่ทำงานเมื่อเรียกใช้*.pywสคริปต์โดยตรง ( ซึ่งตรงข้ามกับการส่งผ่านไฟล์สคริปต์ไปที่pythonw.exe) ดูความคิดเห็นที่ 2 ของeryksunและการติดตามด้านล่าง

คุณสามารถควบคุมไฟล์ที่เรียกใช้สคริปต์ของคุณได้ตามค่าเริ่มต้นเช่นเมื่อเปิดจาก Explorer โดยเลือกนามสกุลไฟล์ที่ถูกต้อง :

  • *.py ไฟล์จะสัมพันธ์กับค่าเริ่มต้น (เรียกใช้) ด้วย python.exe
  • *.pyw ไฟล์จะสัมพันธ์กับค่าเริ่มต้น (เรียกใช้) ด้วย pythonw.exe

1
PS: มันทำงานเมื่อฉันท่อ stdout และ stderr ที่ไหนสักแห่ง: > pythonw ls.pyw >nul 2>&1(แม้ว่าจะไม่มีอะไรเขียน)
จัดการกับ

1
ลักษณะการทำงานแบบซิงโครนัสและแบบอะซิงโครนัสนั้นมาจากพรอมต์คำสั่งแบบโต้ตอบ cmd.exe โดยไม่ต้องใช้startคำสั่ง มันตรวจสอบกระบวนการPEBของลูกเพื่อตรวจสอบว่าเป็นกระบวนการคอนโซลหรือไม่ กระบวนการโฮสต์คอนโซล (conhost.exe) ไม่สนใจสิ่งนี้ หากคุณใช้subprocess.Popenเพื่อเชื่อมต่อpython.exeอินสแตนซ์อื่นกับคอนโซลปัจจุบันและไม่waitติดไว้คุณจะมีความสับสนในการทำงานของทั้งสองกระบวนการในการเข้าถึงคอนโซลพร้อมกัน
Eryk Sun

2
NtCreateUserProcessกระบวนการโหมดผู้ใช้ถูกสร้างขึ้นโดยการโทรระบบ หากเป้าหมายที่เรียกใช้งานได้คือโปรแกรมคอนโซลระบบจะสืบทอดการจัดการมาตรฐานของพาเรนต์แบบไม่มีเงื่อนไข แต่สำหรับโปรแกรมที่ไม่ใช่คอนโซลนั้นจำเป็นต้องได้รับการบอกกล่าวอย่างชัดเจนว่าให้สืบทอดจุดจับที่สืบทอดได้ของผู้ปกครอง เมื่อต้องการเรียกใช้ไฟล์ที่อยู่บนพื้นฐานของความสัมพันธ์ของแฟ้มโทร cmd ShellExecuteExซึ่งจะจับไม่ได้สืบทอดอย่างชัดเจนเมื่อมันเรียก=>CreateProcess NtCreateUserProcessดังนั้นการเปลี่ยนเส้นทาง I / O มาตรฐานจะทำงานใน cmd เมื่อเริ่มต้นสคริปต์. py สคริปต์ แต่ไม่ใช่สคริปต์. pyw สคริปต์ที่ไม่ใช่คอนโซล
Eryk Sun

2
cmd เปลือกพยายามครั้งแรกCreateProcessที่มีการส่งผ่านเป็นbInheritHandles TRUEจะล้มลงอีกShellExecuteExเมื่อCreateProcessล้มเหลวเนื่องจากเป้าหมายไม่ใช่ไฟล์ปฏิบัติการ PE (เช่นเป็นสคริปต์. py) หรือต้องการการยกระดับ (เช่น osk.exe) ดังนั้นเมื่อคุณเรียกใช้โดยตรงpythonw.exeหรือpyw.exeมันจะได้รับมรดกของ cmd StandardInput, StandardOutputและStandardErrorซึ่ง cmd (ที่จริงจอ CRT) ปรับเปลี่ยนผ่านSetStdHandleก่อนและหลังการเรียกร้องCreateProcessเมื่อมาตรฐาน I / O เปลี่ยนเส้นทางไปยังท่อไฟล์หรืออุปกรณ์
Eryk Sun

2
โปรดทราบว่าคำสั่งไม่ได้ใช้STARTUPINFOมือจับ (hStdInput, hStdOutput, hStdErr) subprocess.Popenซึ่งแตกต่างจากงูใหญ่ มันสามารถหนีไปได้ด้วยสิ่งนี้เพราะมันเป็นโปรแกรมแบบเธรดเดียว เป็นเพราะการออกแบบนี้ที่การเปลี่ยนเส้นทางใช้งานได้กับShellExecuteEx(สำหรับโปรแกรมคอนโซลตามที่ระบุไว้) เนื่องจาก GUI เชลล์ API API ไม่สนับสนุน I / O มาตรฐาน
Eryk Sun

19

ดูที่นี่: http://docs.python.org/using/windows.html

pythonw.exe "สิ่งนี้จะระงับหน้าต่างเทอร์มินัลเมื่อเริ่มต้น"


8
pythonw.exeมีผลข้างเคียงที่โปรแกรมของคุณอาจล้มเหลวได้มากมายถ้ามันเขียนไปยัง stdout / stderr stream - ดูbugs.python.org/issue706263
Anatoly techtonik

16

หากคุณกำลังจะเรียกสคริปต์หลามจากกระบวนการอื่น ๆ (พูดจากบรรทัดคำสั่ง), pythonw.exeการใช้งาน มิฉะนั้นผู้ใช้ของคุณจะเห็นอย่างต่อเนื่องcmdหน้าต่างเปิดตัวกระบวนการงูหลามมันจะยังคงเรียกใช้สคริปต์ของคุณเหมือนกัน แต่จะไม่ก้าวก่ายประสบการณ์ผู้ใช้

ตัวอย่างอาจส่งอีเมล python.exeจะปรากฏหน้าต่าง CLI ส่งอีเมลจากนั้นปิดหน้าต่าง มันจะปรากฏเป็นแฟลชด่วนและถือได้ว่าค่อนข้างน่ารำคาญ pythonw.exeหลีกเลี่ยงสิ่งนี้ แต่ยังคงส่งอีเมล


6
จริง แต่อีก "พูดจากบรรทัดคำสั่ง": หากคุณมีในคอนโซล (Terminal) หน้าต่างแล้วpython.exeจะไม่ได้เปิดอีกคนหนึ่ง
mklement0

2

ฉันดิ้นรนเพื่อให้เรื่องนี้ทำงานได้ระยะหนึ่ง เมื่อคุณเปลี่ยนนามสกุลเป็น. pyw ตรวจสอบให้แน่ใจว่าคุณเปิดคุณสมบัติของไฟล์และกำหนดพา ธ "open with" ไปยัง pythonw.exe


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