ความแตกต่างระหว่างโพรเซสย่อย Popen และการโทร (ฉันจะใช้ได้อย่างไร)


178

ฉันต้องการเรียกโปรแกรมภายนอกจาก Python ฉันใช้ทั้งสองPopen()และcall()ทำสิ่งนั้น

ความแตกต่างระหว่างสองคืออะไร

เป้าหมายเฉพาะของฉันคือการเรียกใช้คำสั่งต่อไปนี้จาก Python ฉันไม่แน่ใจว่าการเปลี่ยนเส้นทางทำงานอย่างไร

./my_script.sh > output

ฉันอ่านเอกสารและมันบอกว่าcall()เป็นฟังก์ชั่นอำนวยความสะดวกหรือฟังก์ชั่นทางลัด เราสูญเสียพลังงานโดยการใช้call()แทนPopen()หรือไม่?


เอกสารส่วนใดที่ทำให้คุณสับสน คำจำกัดความของcall()ดูเหมือนจะชัดเจนมาก คุณช่วยเสนอราคาหรือลิงค์เพื่อให้เรารู้ว่าจะให้ความสำคัญกับคำตอบอย่างไร?
S.Lott

คำตอบ:


265

การเปลี่ยนเส้นทางทำได้สองวิธี ทั้งนำไปใช้อย่างใดอย่างหนึ่งหรือsubprocess.Popensubprocess.call

  1. ตั้งค่าอาร์กิวเมนต์คำหลักshell = Trueหรือexecutable = /path/to/the/shellและระบุคำสั่งเช่นเดียวกับที่คุณมี

  2. เนื่องจากคุณเพิ่งเปลี่ยนเส้นทางไปยังไฟล์ให้ตั้งค่าอาร์กิวเมนต์คำหลัก

    stdout = an_open_writeable_file_object

    เมื่อวัตถุชี้ไปที่outputไฟล์

subprocess.Popensubprocess.callทั่วไปมากกว่า

Popenไม่ปิดกั้นช่วยให้คุณสามารถโต้ตอบกับกระบวนการในขณะที่ทำงานหรือดำเนินการกับสิ่งอื่นในโปรแกรม Python ของคุณ การเรียกPopenคืนPopenวัตถุ

call ไม่บล็อก ในขณะที่มันสนับสนุนอาร์กิวเมนต์เดียวกันทั้งหมดเป็นตัวPopenสร้างดังนั้นคุณยังสามารถตั้งค่าเอาท์พุทของกระบวนการตัวแปรสภาพแวดล้อม ฯลฯ สคริปต์ของคุณรอให้โปรแกรมเสร็จสมบูรณ์และcallส่งคืนรหัสที่แสดงถึงสถานะการออกของกระบวนการ

returncode = call(*args, **kwargs) 

โดยพื้นฐานแล้วเหมือนกับการโทร

returncode = Popen(*args, **kwargs).wait()

callเป็นเพียงฟังก์ชั่นอำนวยความสะดวก การใช้งานใน CPython อยู่ในsubprocess.py :

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

Popenที่คุณสามารถดูมันเป็นห่อหุ้มรอบบาง


17
โดยทั่วไป Popen และ call เป็นฟังก์ชันแบบอะซิงโครนัสและซิงโครนัสตามลำดับที่ใช้เรียกใช้คำสั่ง Linux
user3016020

1
ข้อดีของการใช้ popen คืออะไร จะปลอดภัยหรือไม่ที่จะรอจนกระทั่งโปรแกรมที่เรียกใช้เสร็จสิ้นก่อน
Tom

4
@Tom มักจะไม่ ถ้าคุณต้องการอ่านเอาต์พุตบางตัวจากนั้นส่งอินพุตเพิ่มเติมไปยังโปรแกรมอ่านเอาต์พุตเพิ่มเติมที่เป็นผลลัพธ์จากอินพุตนั้นทำซ้ำ?
agf

@ user3016020 ฉันถือว่านี่ใช้กับคำสั่ง Windows ได้หรือไม่ ขวา?
domih

7

คำตอบอื่น ๆ นั้นสมบูรณ์มาก แต่นี่เป็นกฎง่ายๆ:

  • call กำลังปิดกั้น:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
  • Popen ไม่มีการปิดกั้น:

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