練習(xí) 13-15 笨辦法學(xué)Python3

練習(xí) 13 參數(shù),解包,變量

在這個練習(xí)中我們將會再涉及一種 input 方法,你可以用這種方法把變量傳給一個腳本(也就是你的 .py 文件)。你知道如何運行 ex13.py 吧?輸入 python3.6 ex13.py 就行(Windows 下輸入 python ex13.py )。這句命令的 ex13.py 就叫做參數(shù)(argument)。我們現(xiàn)在要做的就是寫一個也接受參數(shù)的腳本。

輸入這個程序,然后我會詳細解釋:

ex13.py

1   from sys import argv
2   # read the WYSS section for how to run this
3   script, first, second, third = argv 
4
5   print("The script is called:", script)
6   print("Your first variable is:", first)
7   print("Your second variable is:", second)
8   print("Your third variable is:", third)

第一行我們進行了 “import”(導(dǎo)入),這能讓你把 Python 功能庫中的功能(features)添加到你的腳本中。Python 會問你你想用什么,而不是一次把所有的功能都給你。它會讓你的程序很小,但是它同時也可以為其它閱讀你代碼的程序員提供參考。

這個 argv 是 “argument variable” ,一個在編程語言中非常標(biāo)準的名字,你會在其它很多的語言中看到它的使用。當(dāng)你運行 Python 腳本的時候,這個變量(variable)保存了你傳給 Python 腳本的參數(shù)(argument)。在這個練習(xí)中,你會做更多相關(guān)的練習(xí),看看會發(fā)生什么。

第三行“解包”(unpacks)了 argv ,而不是保留所有的參數(shù),它分成了四個變量:script, first, second, 以及 third 。這可能看起來很奇怪,但是“解包”這個詞可能是對這個操作的最好定義,就好像在說:“把 argv 里面的東西解包,然后按順序分配給從左到右每一個變量。最后就像平常一樣把它們打印出來即可。

等等!Features 還有另一個名字

我在這兒把它們叫做 features (就是你導(dǎo)入進來讓 python 做更多事情的東西),但是很少有人叫它們 features。我用這個名字只是因為我想讓你在專業(yè)術(shù)語之外思考它們的真正含義。不過在你繼續(xù)學(xué)習(xí)之前,你需要知道它們真正的名字:modules (模塊)。

從現(xiàn)在開始我們會把這些 features 說成導(dǎo)入模塊,比如,“你想導(dǎo)入 sys 模塊”。
它們還被有些程序員叫做“l(fā)ibraries”(庫),但是我們就用模塊這個名字吧。

你會看到

警告!
注意!你之前一直直接運行 python 腳本,不用輸入命令行參數(shù)。如果你只輸入 python3.6 ex13.py 你就錯了!注意看我是怎么操作的,這在任何有 argv 的地方都會用到。

像這樣運行這個程序,前面是你要傳遞的命令行參數(shù):

練習(xí) 13 會話

$ python3.6 ex13.py first 2nd 3rd 
The script is called: ex13.py 
Your first variable is: first 
Your second variable is: 2nd
Your third variable is: 3rd

當(dāng)你做一些不同參數(shù)的運行時,你會看到:

練習(xí) 13 會話

$ python3.6 ex13.py stuff things that  
The script is called: ex13.py
Your first variable is: stuff 
Your second variable is: things 
Your third variable is: that
$
$ python3.6 ex13.py apple orange  grapefruit 
The script is called: ex13.py
Your first variable is: apple 
Your second variable is: orange
Your third variable is: grapefruit

事實上你還可以把 first,2nd,3rd 替換成任何你想替換的東西。如果你沒有正確運行,你會收到這樣的報錯:

練習(xí) 13 會話

$ python3.6 ex13.py first 2nd     
Traceback (most recent call last):
   File "ex13.py", line 3, in <module>    
      script, first, second, third = argv
ValueError: not enough values to unpack (expected 4, got 3)

這種情況一般是當(dāng)你運行腳本的時候沒有在命令行放足夠的變量(在本例中只有 first 、2nd )。注意當(dāng)我運行的時候只給出 first 、2nd ,就會出現(xiàn)錯誤說“需要三個以上的值來解包”,這就是告訴你,你沒有給到足夠多的參數(shù)?!?/p>

附加練習(xí)

  1. 試著給你的腳本三個以內(nèi)的參數(shù),看看你會收到什么樣的報錯,你是否能解釋它。
  2. 寫一個參數(shù)少的腳本和一個參數(shù)多的腳本,給未解包的變量起個合適的名字。
  3. inputargv 結(jié)合起來創(chuàng)建一個腳本,從用戶那里獲取更多 input 。別想得太難,就用 argv 來獲取一些東西,再用 input 從用戶那里獲取一些東西。
  4. 記住模塊給我們一些特征,記住它叫模塊(modules),我們之后會用到。

常見問題

當(dāng)我運行的時候我收到了 ValueError: need more than 1 value to unpack.還記得我說過,學(xué)習(xí)編程的一項重要技能就是注意細節(jié)。如果你看了“你會看到”那部分,你就會看到我是如何在命令行上運行有參數(shù)的腳本的,你應(yīng)該準確按照我做的來。

argvinput() 之間的區(qū)別是什么? 區(qū)別取決于用戶在哪被要求輸入,如果是在命令行,就用 argv。如果你想讓它們在程序已經(jīng)運行的情況下用鍵盤輸入,那就用 input() 。

命令行參數(shù)是字符串嗎?是的,它們是以字符串的形式進來的,即使你在命令行輸入的是數(shù)字。你可以用 int() 把它們轉(zhuǎn)化成數(shù)值,就像 int(input())

你如何使用用命令行?” 你應(yīng)該已經(jīng)學(xué)過命令行的使用了,現(xiàn)在應(yīng)該用得很 6 了。但是如果你還沒有學(xué),先去附錄 A 學(xué)習(xí)命令行速成課程。

我不知道怎么把 argvinput() 結(jié)合在一起。 別把它想得太難。就在腳本最后加兩行,用 input() 獲取一些東西,再打印出來。然后試著用更多方式在同一個腳本中使用這兩樣?xùn)|西。

為什么我不能這樣用:input('? ') = x ? 因為它寫反了,按我的要求寫,就能運行。

練習(xí) 14 提示和傳遞

讓我們來做一個把 argvinput 結(jié)合在一起的練習(xí)來問用戶一些特別的問題。這些問題會在你學(xué)習(xí)下一個練習(xí)中閱讀和寫文件的時候用到。在這個練習(xí)中我們會用一種不同的方式使用 input ,就是讓它打印出一個簡單的 > 提示符。這有點像 Zork 或者 Adventure 這兩款游戲。

ex14.py

1   from sys import argv 
2
3   script, user_name = argv
4   prompt = '> ' 
5
6   print(f"Hi {user_name}, I'm the {script} script.")
7   print("I'd like to ask you a few questions.")
8   print(f"Do you like me {user_name}?")
9   likes = input(prompt) 
10
11  print(f"Where do you live {user_name}?")
12  lives = input(prompt) 
13
14  print("What kind of computer do you have?")
15  computer = input(prompt) 
16
17  print(f"""
18  Alright, so you said {likes} about liking me.
19  You live in {lives}. Not sure where that is.
20  And you have a {computer} computer. Nice. 
21  """)

我們把用戶提示符設(shè)置成變量 prompt ,然后把它賦給 input 而不是一遍遍地輸入它們?,F(xiàn)在如果我們想把提示符變成別的東西,只要修改一個地方,然后重新運行腳本即可,非常方便。

你會看到

當(dāng)你運行腳本的時候,記住一定要把你的名字賦給這個腳本,讓 argv 接收到你的名字。

練習(xí) 14 會話

$ python3.6 ex14.py zed
Hi zed, I'm the ex14.py script.
I'd like to ask you a few questions. 
Do you like me zed?
>   Yes
Where do you live zed?
>   San Francisco
What kind of computer do you have?
>   Tandy 1000

Alright, so you said Yes about liking me.
You live in San Francisco. Not sure where that is. 
And you have a Tandy 1000 computer. Nice.

附加練習(xí)

  1. 查查看 Zork 和 Adventure 游戲是什么,找來玩玩。
  2. prompt 變量改成別的東西。
  3. 在你的腳本里再加一個參數(shù),就像之前練習(xí)中 first, second = argv 一樣。
  4. 確定你理解了我是如何在最后一行把 """ 多行格式字符(style multiline string)和 {} 格式激活器(format activator)結(jié)合起來的。

常見問題

我運行腳本的時候收到了 SyntaxError: invalid syntax我再說一次,你得在命令行里運行它,而不是在 python 里。如果你輸入 python3.6,然后再輸入 python3.6 ex14.py Zed ,就會無法運行,因為你是在 python 里面運行 python。關(guān)掉窗口,然后只輸入 python3.6 ex14.py Zed

你說的“改變提示符”是什么意思?我不太理解。看到這個變量 prompt = '>' 了嗎?改變它的值。你知道的,它只是一個字符串,你已經(jīng)做了 13 個練習(xí)來創(chuàng)建它們了,所以好好想想,把它弄明白。

我收到了報錯信息:ValueError: need more than 1 value to unpack. 我前面說過,你需要看看“你會看到”那部分然后復(fù)制我的做法。這兒也一樣,注意我是如何輸入命令行的,以及我為什么有一個命令行參數(shù)。

我如何從 IDLE 來運行這些?不要用 IDLE。

我能在 prompt 變量外面用雙引號嗎?你完全可以,試試吧。

你有一臺 Tandy computer?是的,在我很小的時候。

我運行的時候收到了報錯信息:NameError: name 'prompt' is not defined 。 你要么把 prompt 變量拼寫錯了,要么把那行漏掉了。回過頭去,從下到上比較每一行代碼。你一旦遇到這種報錯,就說明你拼寫錯誤或者忘了創(chuàng)建變量。

練習(xí) 15 閱讀文件

你已經(jīng)知道如何用 input 或者 argv 來獲取用戶的輸入了?,F(xiàn)在你將學(xué)習(xí)如何閱讀文件。你需要好好做這個練習(xí),才能理解發(fā)生了什么,記住要仔細輸入和檢查。對文件進行操作很容易把文件刪掉,所以你要千萬小心。

在這個練習(xí)中你要寫兩個文件。一個是通常你要運行的 ex15.py ,一個是叫做 ex15_sample.txt 的文本文件。以下是文本文件中要輸入的內(nèi)容:

This is stuff I typed into a file. 
It is really cool stuff.
Lots and lots of fun to have in here.

我們要做的就是在我們的腳本中打開這個文件并把它打印出來。然而,我們不想只是簡單粗暴(hard coding)地把 ex15_sample.txt 這個文件名輸入進去,hard coding 的意思是把一些應(yīng)該從用戶那里獲取的信息直接放到源代碼里。這樣不好,因為我們隨后會需要它載入別的文件。解決方法是用 argv 或者 input 來問用戶應(yīng)該打開哪個文件,而不是 hard coding 文件名。

ex15.py

1   from sys import argv 
2
3   script, filename = argv 
4
5   txt = open(filename) 
6
7   print(f"Here's your file {filename}:")
8   print(txt.read()) 
9
10  print("Type the filename again:")
11  file_again = input("> ") 
12
13  txt_again = open(file_again) 
14
15  print(txt_again.read())

這個文件里發(fā)生了一些奇妙的事情,讓我們快速分解來看一下:

第 1-3 行用了 argv 來獲取一個文件名,然后第 5 行用了一個新的命令 open ?,F(xiàn)在,運行 pydoc open 然后閱讀說明。看見了吧,就像你自己的腳本和輸入,它用了一個參數(shù)(parameter)然后返回了一個值,你可以把它賦給你自己的變量。你只是打開了一個文件。

第 7 行打印了一些信息,第 8 行就有一些新東西了。我們對 txt 用了一個叫做 read. 的函數(shù),你從 open 那里得到的是一個文件,而且你還可以通過 . 命令名,以及參數(shù),來給它一個命令,就像用 openinput 那樣。區(qū)別是,txt.(read) 是說:txt ,執(zhí)行不帶參數(shù)的 read 命令!

剩下的部分基本上類似,但是我們會把分析留到附加練習(xí)里。

你會看到

警告!
注意!你一直通過輸入文件名來運行腳本,但是你要用 argv 加上參數(shù)來運行。看看下面例子的第一行,你會看我是通過輸入 python ex15.py ex15_sample.txt 來運行它的。 ex15.py 后面的內(nèi)容就是你要輸入的參數(shù),如果你漏掉了,就會收到報錯信息!所以千萬要注意!

我創(chuàng)建了一個叫做 ex15_sample.txt 的文件來運行我的腳本。

練習(xí) 15 會話

$ python3.6 ex15.py ex15_sample.txt  
Here's your file ex15_sample.txt: 
This is stuff I typed into a file. 
It is really cool stuff.
Lots and lots of fun to have in here.

Type the filename again:
>   ex15_sample.txt
This is stuff I typed into a file. 
It is really cool stuff.
Lots and lots of fun to have in here.

附加練習(xí)

這部分可能比較難,在你往下進行之前,確保你盡力去做這個附加練習(xí)。

  1. 在每行上面添加注釋解釋其含義。
  2. 如果你不確定,上網(wǎng)搜,或者問別人,比如你不知道 open 的用法,直接搜 python3.6 open 即可。
  3. 我在這兒用的是“命令”(command)這個詞,不過,它也叫“函數(shù)”(function)或者“方法”(method)。你會在本書后面學(xué)到 functions 和 methods。
  4. 把第 10-15 行刪掉(或者用別的方法使其失效)然后再運行腳本。
  5. 只用 input 來試試運行這個腳本。為什么要獲取文件名的話一種方法比另一種方法更好?
  6. 開啟 python3.6 shell,然后就像這個程序中一樣從提示界面用 open。注意你是如何從 python3.6 里面打開文件并運行 read 的?
  7. 在你的腳本中對 txt 調(diào)用 close() 以及 txt_again 變量。當(dāng)你對它們完成操作后關(guān)掉文件是非常重要的。

常見問題

txt = open(filename) 會返回文件的內(nèi)容嗎? 不會。它其實是創(chuàng)建了一個叫做“文件對象”(file object)的東西。你可以把它想象成曾經(jīng)的 DVD 播放器,你可以在里面移動然后“讀取”它們。但是 DVD 播放器不是 DVD 本身,就像文件對象也不是文件本身一樣。

我無法像你附加練習(xí) 7 中說的那樣在 Terminal/PowerShell 里輸入代碼。 首先,在命令行輸入 python3.6 然后敲回車?,F(xiàn)在你已經(jīng)在 python3.6 里面了。然后你可以輸入代碼,python 就會運行一些。試著這樣玩玩,然后輸入 quit() 并回車,退出。

為什么打開文件兩次不會收到報錯?
Python 不會限制你只能打開一次文件,事實上有時候確實需要打開多次。

from sys import argv 是什么意思?現(xiàn)在你只需要明白 sys 是一個包(package),這個短語是說從那個包里獲取 argv 功能(feature)。你會在后面深入學(xué)習(xí)這塊內(nèi)容。

我把腳本文件名這樣放進去:ex15_sample.txt = argv, 但是無法運行。 你不能這樣做。嚴格按照我的代碼來,然后用同樣的方法在命令行運行它。你不用把文件名放進去,你得讓 python 自己放。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容