sys.argv [1] ความหมายในสคริปต์


146

ฉันกำลังสอน Python อยู่และกำลังสงสัย (อ้างอิงจากตัวอย่างด้านล่าง) ด้วยคำศัพท์ที่เข้าใจง่ายสิ่งที่สื่อsys.argv[1]ถึง มันเป็นเพียงแค่ขอให้ป้อนข้อมูลหรือไม่

#!/usr/bin/python3.1

# import modules used here -- sys is a very standard one
import sys

# Gather our code in a main() function
def main():
  print ('Hello there', sys.argv[1])
  # Command line args are in sys.argv[1], sys.argv[2] ..
  # sys.argv[0] is the script name itself and can be ignored

# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
  main()

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

คำตอบ:


334

ฉันต้องการที่จะทราบว่าคำตอบก่อนหน้านี้ทำให้สมมติฐานมากมายเกี่ยวกับความรู้ของผู้ใช้ คำตอบนี้พยายามตอบคำถามในระดับการสอนเพิ่มเติม

สำหรับการเรียกใช้งานของ Python ทุกครั้งsys.argvจะมีรายการของสตริงที่แสดงถึงข้อโต้แย้งโดยอัตโนมัติ (ตามที่คั่นด้วยช่องว่าง) บนบรรทัดคำสั่ง ชื่อมาจากการประชุมการเขียนโปรแกรม Cซึ่ง argv และ argc แสดงถึงอาร์กิวเมนต์บรรทัดคำสั่ง

คุณจะต้องการเรียนรู้เพิ่มเติมเกี่ยวกับรายการและสตริงในขณะที่คุณกำลังคุ้นเคยกับ Python แต่ในระหว่างนี้นี่เป็นสิ่งที่ควรรู้

คุณสามารถสร้างสคริปต์ที่พิมพ์อาร์กิวเมนต์ตามที่แสดง นอกจากนี้ยังพิมพ์จำนวนอาร์กิวเมนต์โดยใช้lenฟังก์ชันในรายการ

from __future__ import print_function
import sys
print(sys.argv, len(sys.argv))

สคริปต์ต้องการ Python 2.6 หรือใหม่กว่า หากคุณเรียกใช้สคริปต์นี้print_args.pyคุณสามารถเรียกใช้พร้อมอาร์กิวเมนต์ที่แตกต่างกันเพื่อดูว่าเกิดอะไรขึ้น

> python print_args.py
['print_args.py'] 1

> python print_args.py foo and bar
['print_args.py', 'foo', 'and', 'bar'] 4

> python print_args.py "foo and bar"
['print_args.py', 'foo and bar'] 2

> python print_args.py "foo and bar" and baz
['print_args.py', 'foo and bar', 'and', 'baz'] 4

อย่างที่คุณเห็นอาร์กิวเมนต์บรรทัดคำสั่งมีชื่อสคริปต์ แต่ไม่ใช่ชื่อล่าม ในกรณีนี้ Python ให้สคริปต์เป็นไฟล์ที่เรียกใช้งานได้ หากคุณจำเป็นต้องรู้ชื่อของไฟล์ที่สามารถใช้งานsys.executableได้(ไพ ธ อนในกรณีนี้) คุณสามารถใช้

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

ตอนนี้ในรหัส Python ของคุณคุณสามารถใช้รายการสตริงนี้เป็นอินพุตของโปรแกรมของคุณ เนื่องจากรายการจะถูกจัดทำดัชนีโดยจำนวนเต็มตามศูนย์คุณสามารถรับแต่ละรายการโดยใช้รายการ [0] ตัวอย่างเช่นในการรับชื่อสคริปต์:

script_name = sys.argv[0] # this will always work.

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

filename = sys.argv[1]

นี่เป็นการใช้งานทั่วไป แต่โปรดทราบว่ามันจะล้มเหลวด้วย IndexError หากไม่มีการระบุอาร์กิวเมนต์

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

user_args = sys.argv[1:] # get everything after the script name

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

user_args = sys.argv[1:]
fun, games = user_args # len(user_args) had better be 2

ดังนั้นเพื่อตอบคำถามเฉพาะของคุณsys.argv[1]แสดงถึงอาร์กิวเมนต์บรรทัดคำสั่งแรก (เป็น a string) ที่ส่งให้กับสคริปต์ที่เป็นปัญหา มันจะไม่พร้อมท์ให้ป้อนข้อมูล แต่จะล้มเหลวด้วย IndexError หากไม่มีการระบุอาร์กิวเมนต์บนบรรทัดคำสั่งตามชื่อสคริปต์


1
เมื่อคุณแสดงรายการของสตริงsys.argvฉันสงสัยว่าบรรทัดfrom __future__ import print_functionทำอะไร เป็นสิ่งที่ฉันต้องเพิ่มหรือไม่หากฉันไม่ได้ใช้งาน Python 3 แต่เป็น Python 2 @Jason R. Coombs
Nicholas

1
@NicholasLiu คุณไม่จำเป็นต้องเพิ่มถ้าคุณใช้ Python 3 ฉันเพิ่มเพื่อความสมบูรณ์ ลองใช้โดยไม่ใช้ Python 2 และคุณจะได้ผลลัพธ์ที่แตกต่างจากที่ฉันอธิบายไว้ ให้มันลอง.
Jason R. Coombs

@ JasonR.Coombs sys.argv **is** automatically a list of stringsฉันสับสนกับคนนี้: คุณหมายถึง "ให้" หรือ "กลับมา"
JinSnow

1
@ Guillaume: มันเป็นความแตกต่างทางความหมายที่ลึกซึ้ง แต่ใน Python ชื่อเช่น sys.argv จะเก็บการอ้างอิงไปยังวัตถุ ดังนั้นในทางเทคนิคแล้วargvแอตทริบิวต์ของsysโมดูลเป็นการอ้างอิงไปยังวัตถุรายการที่มีสตริงของการขัดแย้ง หากต้องการใช้givesหรือreturnsแนะนำการเรียกใช้ฟังก์ชันหรือตัวสร้างหรือโครงสร้างอื่น referencesหรือrepresentsอาจเป็นคำที่แม่นยำกว่า แต่isใกล้พอ
Jason R. Coombs

@ JasonR.Coombs จะเกิดอะไรขึ้นถ้าฉันเรียกโดยตรงmainโดยการนำเข้าโมดูล (สมมติว่าชื่อโมดูลคือmoduleA.py) และเรียกใช้ฟังก์ชันตามimport moduleA; moduleA.main()มา ในกรณีที่ไม่มีอาร์กิวเมนต์บรรทัดคำสั่ง .. ดังนั้นจะsys.argv[0]ยังคงควรจะเป็นตัวแทนของfilenameคือ มันควรจะพิมพ์ออกมาmoduleA.py?
alpha_989

34

sys.argv [1]มีอาร์กิวเมนต์บรรทัดคำสั่ง แรกที่ส่งผ่านไปยังสคริปต์ของคุณ

ตัวอย่างเช่นหากสคริปต์ของคุณชื่อhello.pyและคุณออก:

$ python3.1 hello.py foo

หรือ:

$ chmod +x hello.py  # make script executable
$ ./hello.py foo

สคริปต์ของคุณจะพิมพ์:

สวัสดีที่นั่นฟู

ฉันต้องเรียกใช้คำสั่งนี้: exec py C: \\ project-open \\ เซิร์ฟเวอร์ \\ projop \\ แพคเกจ \\ อินทราเน็ต - timesheet2 \\ www \\ ชั่วโมง \\ y.py มีวิธีใช้เส้นทางสัมพัทธ์สำหรับ ไฟล์หลาม?
yaksh

25

sys.argv เป็นรายการ

รายการนี้สร้างโดยบรรทัดคำสั่งของคุณเป็นรายการอาร์กิวเมนต์บรรทัดคำสั่งของคุณ

ตัวอย่างเช่น:

ในบรรทัดคำสั่งของคุณคุณป้อนสิ่งนี้

python3.2 file.py something

sys.argv จะกลายเป็นรายการ ['file.py', 'อะไรบางอย่าง']

ในกรณีนี้ sys.argv[1] = 'something'


12

เพียงเพิ่มคำตอบของ Frederic ตัวอย่างเช่นถ้าคุณเรียกสคริปต์ของคุณดังนี้:

./myscript.py foo bar

sys.argv[0]จะเป็น "./myscript.py" sys.argv[1]จะเป็น "foo" และ sys.argv[2]จะเป็น "bar" ... เป็นต้น

ในโค้ดตัวอย่างของคุณถ้าคุณเรียกสคริปต์ดังต่อไปนี้ ./myscript.py foo ผลลัพธ์ของสคริปต์จะเป็น "Hello there foo"


9

การเพิ่มคะแนนอีกเล็กน้อยในคำตอบของ Jason:

สำหรับการรับอาร์กิวเมนต์ทั้งหมดที่ผู้ใช้ระบุ: user_args = sys.argv[1:]

พิจารณา sys.argv เป็นรายการสตริงตาม (กล่าวถึงโดย Jason) ดังนั้นการจัดการรายการทั้งหมดจะใช้ที่นี่ สิ่งนี้เรียกว่า "การแบ่งรายชื่อ" สำหรับการเยี่ยมชมข้อมูลเพิ่มเติมได้ที่นี่

ไวยากรณ์เป็นดังนี้: list [start: end: step] หากคุณละเว้นการเริ่มต้นระบบจะใช้ค่าเริ่มต้นเป็น 0 และหากคุณไม่ระบุก็จะเริ่มต้นตามความยาวของรายการ

สมมติว่าคุณต้องการรับอาร์กิวเมนต์ทั้งหมดหลังจากอาร์กิวเมนต์ที่ 3 เท่านั้นจากนั้น:

user_args = sys.argv[3:]

สมมติว่าคุณต้องการอาร์กิวเมนต์สองข้อแรกเท่านั้นจากนั้น:

user_args = sys.argv[0:2]  or  user_args = sys.argv[:2]

สมมติว่าคุณต้องการอาร์กิวเมนต์ 2 ถึง 4:

user_args = sys.argv[2:4]

สมมติว่าคุณต้องการอาร์กิวเมนต์สุดท้าย (อาร์กิวเมนต์สุดท้ายเสมอ -1 ดังนั้นสิ่งที่เกิดขึ้นที่นี่คือเราเริ่มนับจากด้านหลังดังนั้นการเริ่มต้นเป็นครั้งสุดท้ายไม่สิ้นสุดไม่มีขั้นตอน):

user_args = sys.argv[-1]

สมมติว่าคุณต้องการอาร์กิวเมนต์สุดท้ายที่สอง:

user_args = sys.argv[-2]

สมมติว่าคุณต้องการอาร์กิวเมนต์สองตัวสุดท้าย:

user_args = sys.argv[-2:]

สมมติว่าคุณต้องการอาร์กิวเมนต์สองตัวสุดท้าย ที่นี่การเริ่มต้นคือ -2 นั่นคือรายการสุดท้ายที่สองและต่อท้าย (แสดงโดย ":"):

user_args = sys.argv[-2:]

สมมติว่าคุณต้องการทุกอย่างยกเว้นอาร์กิวเมนต์สองข้อสุดท้าย ที่นี่เริ่มต้นเป็น 0 (โดยค่าเริ่มต้น) และสิ้นสุดเป็นรายการสุดท้ายที่สอง:

user_args = sys.argv[:-2]

สมมติว่าคุณต้องการอาร์กิวเมนต์ในลำดับย้อนกลับ:

user_args = sys.argv[::-1]

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


4

sys.argv เป็นรายการที่มีเส้นทางสคริปต์และอาร์กิวเมนต์บรรทัดคำสั่ง; ie sys.argv [0] เป็นเส้นทางของสคริปต์ที่คุณกำลังเรียกใช้และสมาชิกต่อไปนี้ล้วน แต่เป็นข้อโต้แย้ง


3

เพื่อส่งผ่านอาร์กิวเมนต์ไปยังสคริปต์ python ของคุณขณะเรียกใช้สคริปต์ผ่านบรรทัดคำสั่ง

python create_thumbnail.py test1.jpg test2.jpg

ที่นี่ชื่อสคริปต์ - create_thumbnail.py, อาร์กิวเมนต์ 1 - test1.jpg, อาร์กิวเมนต์ 2 - test2.jpg

ด้วยในสคริปต์ create_thumbnail.py ฉันใช้

sys.argv[1:]

ซึ่งให้รายการข้อโต้แย้งที่ฉันส่งผ่านในบรรทัดคำสั่งเป็น ['test1.jpg', 'test2.jpg']


1

sys.argvเป็นคุณลักษณะของsysโมดูล มันบอกว่าข้อโต้แย้งที่ส่งผ่านไปยังไฟล์ในบรรทัดคำสั่ง sys.argv[0]จับไดเรกทอรีที่ไฟล์นั้นอยู่ sys.argv[1]ส่งคืนอาร์กิวเมนต์แรกที่ส่งผ่านในบรรทัดคำสั่ง คิดเหมือนเรามีไฟล์ example.py

example.py

import sys # Importing the main sys module to catch the arguments
print(sys.argv[1]) # Printing the first argument

ตอนนี้ที่นี่ในพร้อมท์คำสั่งเมื่อเราทำสิ่งนี้:

python example.py

มันจะโยนข้อผิดพลาดดัชนีที่บรรทัดที่ 2 เนื่องจากยังไม่มีการโต้แย้ง if len(sys.argv) >= 1: # Codeคุณสามารถดูความยาวของการขัดแย้งที่ผ่านมาโดยผู้ใช้ หากเราเรียกใช้ example.py ด้วยการส่งผ่านข้อโต้แย้ง

python example.py args

มันพิมพ์:

args

เพราะมันเป็นการโต้เถียงครั้งแรก! สมมติว่าเราได้ทำให้มันเป็นไฟล์ปฏิบัติการโดยใช้ PyInstaller เราจะทำสิ่งนี้:

example argumentpassed

มันพิมพ์:

argumentpassed

เป็นประโยชน์จริง ๆ เมื่อคุณทำการสั่งการในเทอร์มินัล ตรวจสอบความยาวของอาร์กิวเมนต์ก่อน หากไม่มีการโต้แย้งผ่านให้ทำข้อความช่วยเหลือ


0

sys .argv จะแสดงบรรทัดคำสั่ง args ที่ส่งผ่านเมื่อเรียกใช้สคริปต์หรือคุณสามารถพูดว่า sys.argv จะเก็บอาร์กิวเมนต์บรรทัดคำสั่งที่ส่งผ่านเป็นไพ ธ อนขณะที่รันจากเทอร์มินัล

ลองทำสิ่งนี้:

import sys
print sys.argv

argv เก็บอาร์กิวเมนต์ทั้งหมดที่ส่งผ่านในรายการไพ ธ อน ด้านบนจะพิมพ์ข้อโต้แย้งทั้งหมดที่ผ่านจะใช้สคริปต์

ตอนนี้ให้ลองเรียกใช้ filename.py ของคุณเช่นนี้:

python filename.py example example1

นี้จะพิมพ์ 3 ข้อโต้แย้งในรายการ

sys.argv[0] #is the first argument passed, which is basically the filename. 

ในทำนองเดียวกัน argv 1เป็นอาร์กิวเมนต์แรกที่ส่งผ่านในกรณีนี้ 'ตัวอย่าง'

มีการถามคำถามที่คล้ายกันที่นี่แล้วbtw หวังว่านี่จะช่วยได้!

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