Selenium2自動化測試實戰基於Python語言》讀書筆記--第3章

第3章 Python基礎

由於作者寫的這本書完全是以Python語言爲基礎的,所以需要讀者具備一定的Python編程能力。如果說最好的Python基礎教程,那應該說是《笨方法學Python》了。

3.1 Python哲學

<span style="color:#000000"><code>Python <span style="color:#006666">2.7</span><span style="color:#006666">.13</span> (v2<span style="color:#006666">.7</span><span style="color:#006666">.13</span>:a06454b1afa1, Dec <span style="color:#006666">17</span> <span style="color:#006666">2016</span>, <span style="color:#006666">20</span>:<span style="color:#006666">42</span>:<span style="color:#006666">59</span>) [MSC v<span style="color:#006666">.1500</span> <span style="color:#006666">32</span> bit (Intel)] <span style="color:#000088">on</span> win32
Type <span style="color:#009900">"copyright"</span>, <span style="color:#009900">"credits"</span> <span style="color:#000088">or</span> <span style="color:#009900">"license()"</span> <span style="color:#000088">for</span> more information.
>>> import this
The Zen <span style="color:#000088">of</span> Python, <span style="color:#000088">by</span> Tim Peters

Beautiful <span style="color:#000088">is</span> better than ugly.
Explicit <span style="color:#000088">is</span> better than implicit.
Simple <span style="color:#000088">is</span> better than complex.
Complex <span style="color:#000088">is</span> better than complicated.
Flat <span style="color:#000088">is</span> better than nested.
Sparse <span style="color:#000088">is</span> better than dense.
Readability counts.
Special cases aren't special enough <span style="color:#000088">to</span> break <span style="color:#000088">the</span> rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In <span style="color:#000088">the</span> face <span style="color:#000088">of</span> ambiguity, refuse <span style="color:#000088">the</span> temptation <span style="color:#000088">to</span> guess.
There should be one<span style="color:#880000">-- and preferably only one --obvious way to do it.</span>
Although <span style="color:#000088">that</span> way may <span style="color:#000088">not</span> be obvious <span style="color:#000088">at</span> <span style="color:#000088">first</span> unless you're Dutch.
Now <span style="color:#000088">is</span> better than never.
Although never <span style="color:#000088">is</span> often better than *right* now.
If <span style="color:#000088">the</span> implementation <span style="color:#000088">is</span> hard <span style="color:#000088">to</span> explain, <span style="color:#000088">it</span>'s a bad idea.
If <span style="color:#000088">the</span> implementation <span style="color:#000088">is</span> easy <span style="color:#000088">to</span> explain, <span style="color:#000088">it</span> may be a good idea.
Namespaces are one honking great idea <span style="color:#880000">-- let's do more of those!</span>
>>> </code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

翻譯爲中文就是:

  • 優美勝於醜陋
  • 明瞭勝於晦澀
  • 簡單勝過複雜
  • 扁平勝於嵌套
  • 間隔勝於緊湊
  • 可讀性很重要
  • 即使假錯特例的實用性之名,也不違背這些規則
  • 雖然實用性次於純度
  • 錯誤不應該被無聲的忽略
  • 除非明確的沉默
  • 當存在多種可能時,不要嘗試去猜測
  • 應該有一個,最好只有一個,很明顯可以做到這一點
  • 雖然這種方式可能不容易,除非你是Python之父
  • 現在做總比不做好
  • 雖然過期從未比現在好
  • 如果這個實現不容易解釋,那麼它肯定是壞主意
  • 如果這個實現容易解釋,那麼它很可能是個好主意
  • 命名空間是一種絕妙的理念,應當多加利用

3.2 輸出與輸入

3.2.1 print打印

Python提供print()方法來打印信息:

<span style="color:#000000"><code class="language-python">>>><span style="color:#000088">print</span> (<span style="color:#009900">"hello python"</span>)
hello python</code></span>
  • 1
  • 2

打印變量:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>name = <span style="color:#009900">"zhangsan"</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"hello %s , Nice to meet you!"</span> % name)
hello zhangsan , Nice to meet you!
<span style="color:#006666">>>> </span>name = <span style="color:#009900">"Lisi"</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"hello %s , Nice to meet you!"</span> % name)
hello Lisi , Nice to meet you!</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

%s 只能打印字符串,如果想要打印數組,需要使用%d:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>age = <span style="color:#006666">27</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"You are %d !"</span> % age)
You are <span style="color:#006666">27</span> !</code></span>
  • 1
  • 2
  • 3

如果不知道自己打印的類型,可以使用%r:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>age = <span style="color:#006666">27</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"You are %d !"</span> % age)
You are <span style="color:#006666">27</span> !
<span style="color:#006666">>>> </span>
<span style="color:#006666">>>> </span>n =<span style="color:#006666">100</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"You print is %r ."</span> % n)
You <span style="color:#000088">print</span> <span style="color:#000088">is</span> <span style="color:#006666">100</span> .
<span style="color:#006666">>>> </span>n = <span style="color:#009900">"abc"</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"You print is %r ."</span> % n)
You <span style="color:#000088">print</span> <span style="color:#000088">is</span> <span style="color:#009900">'abc'</span> .
<span style="color:#006666">>>> </span>name = <span style="color:#009900">"zhangsan"</span>
<span style="color:#006666">>>> </span>age = <span style="color:#006666">22</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"student info: %s %d ."</span> % (name, age))
student info: zhangsan <span style="color:#006666">22</span> .</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3.2.2 input輸入

如果希望打印的是程序運行過程中由用戶來決定的內容,可以使用input()方法:

<span style="color:#000000"><code class="language-python">n = input(<span style="color:#009900">"Enter any content: "</span>)
<span style="color:#000088">print</span> <span style="color:#009900">"Your input is %r"</span> % n</code></span>
  • 1
  • 2

運行上述腳本時,用戶輸入的信息就會被打印出來。

3.2.3 引號與註釋

Python不區分單引號、雙引號,都可以用來表示一個字符串:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"hello"</span>)
hello
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">'hello'</span>)
hello</code></span>
  • 1
  • 2
  • 3
  • 4

單引號和雙引號可以相互嵌套使用,但不能交叉使用:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"你說:'早上你好'"</span>)
你說:<span style="color:#009900">'早上你好'</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">'我說:"今天天氣不錯"'</span>)
我說:<span style="color:#009900">"今天天氣不錯"</span>
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> (<span style="color:#009900">"你微笑着'向我道別"</span>。<span style="color:#009900">')

SyntaxError: invalid syntax</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Python的單行註釋使用“#”表示:

<span style="color:#000000"><code class="language-python">>>><span style="color:#880000">#單行註釋</span>
>>><span style="color:#000088">print</span> (<span style="color:#009900">"hello world"</span>) <span style="color:#880000">#打印hello world</span>
hello world</code></span>
  • 1
  • 2
  • 3

多行註釋使用三對引號表示,同樣不區分單、雙引號:

<span style="color:#000000"><code class="language-python"><span style="color:#009900">"""
我們實現一個偉大的程序
那麼是
print 一行數據 ^_^
"""</span>
<span style="color:#009900">'''
This is a
Multi line comment
'''</span>
<span style="color:#000088">print</span> (<span style="color:#009900">"Hello World"</span>)</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.3 分支與循環

結構化程序實質上是由有限個順序、分支和循環三種基本結構排列、嵌套而成。

3.3.1 if語句

if實現分支判斷,一般語法爲:if…else…

<span style="color:#000000"><code class="language-python">>>>a = <span style="color:#006666">2</span>
>>>b = <span style="color:#006666">3</span>
>>><span style="color:#000088">if</span> a > b:
    <span style="color:#000088">print</span> (<span style="color:#009900">"a max!"</span>)
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"b max!"</span>)

b max!</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

注意: Python沒有像其他語言一樣使用“{}”表示語句體,而是通過語句的縮進來判斷語句體,縮進默認爲4個空格。

if語句通過“==”運算符判斷相等:

<span style="color:#000000"><code class="language-python">>>>student = <span style="color:#009900">"xiaoming"</span>
>>><span style="color:#000088">if</span> student == <span style="color:#009900">"xiaoming"</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"xiaoming, You are on duty today."</span>)
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"Please call xiaoming to duty"</span>)

xiaoming, You are on duty today.</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

if語句通過“!=”運算符判斷不相等;

if語句還可以使用“in”、“not in”表示包含關係:

<span style="color:#000000"><code class="language-python">>>>hi = <span style="color:#009900">"hello world"</span>
>>><span style="color:#000088">if</span> <span style="color:#009900">"hello"</span> <span style="color:#000088">in</span> hi:
    <span style="color:#000088">print</span> (<span style="color:#009900">"Contain"</span>)
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"Not Contain"</span>)

Contain</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

if語句還可以進行布爾類型的判斷:

<span style="color:#000000"><code class="language-python">>>>a = <span style="color:#000088">True</span>
>>><span style="color:#000088">if</span> a:
    <span style="color:#000088">print</span> (<span style="color:#009900">"a is True"</span>)
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"a is not True"</span>)

a <span style="color:#000088">is</span> <span style="color:#000088">True</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

練習:

<span style="color:#000000"><code class="language-python">results = <span style="color:#006666">72</span>

<span style="color:#000088">if</span> results >= <span style="color:#006666">90</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"優秀"</span>)
<span style="color:#000088">elif</span> results >= <span style="color:#006666">70</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"良好"</span>)
<span style="color:#000088">elif</span> results >= <span style="color:#006666">60</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"及格"</span>)
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> (<span style="color:#009900">"不及格"</span>)</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

答案:良好。

3.3.2 for語句

Python提供了兩種循環:while循環、for循環。

for循環的使用更加靈活、簡單,可以直接對一個字符串進行遍歷:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">for</span> i <span style="color:#000088">in</span> <span style="color:#009900">"hello world"</span>:
    <span style="color:#000088">print</span> (i)


h
e
l
l
o

w
o
r
l
d</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

對一個字典進行遍歷:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>fruits = [<span style="color:#009900">'banana'</span>, <span style="color:#009900">'apple'</span>, <span style="color:#009900">'mango'</span>]
<span style="color:#006666">>>> </span><span style="color:#000088">for</span> fruit <span style="color:#000088">in</span> fruits:
    <span style="color:#000088">print</span> fruit


banana
apple
mango</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用range()函數來進行指定次數的循環:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">for</span> i <span style="color:#000088">in</span> range(<span style="color:#006666">5</span>):
    <span style="color:#000088">print</span> (i)


<span style="color:#006666">0</span>
<span style="color:#006666">1</span>
<span style="color:#006666">2</span>
<span style="color:#006666">3</span>
<span style="color:#006666">4</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注意: range()函數默認從0開始循環。

指定起始位置和步長的循環:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">for</span> i <span style="color:#000088">in</span> range(<span style="color:#006666">1</span>, <span style="color:#006666">10</span>, <span style="color:#006666">2</span>):
    <span style="color:#000088">print</span> (i)


<span style="color:#006666">1</span>
<span style="color:#006666">3</span>
<span style="color:#006666">5</span>
<span style="color:#006666">7</span>
<span style="color:#006666">9</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

range(start, end[, step]) 
start表示開始位置、end表示結束位置、step表示每一次循環的步長。

python2:range() 是一個生成器,xrange()是一個數組,功能完全一樣,性能後者優於前者; 
python3:range()和xrange()相同,都是一個數組。

3.4 數組與字典

3.4.1 數組

數組:用方括號[]表示,裏面的每一項用逗號“,”分隔。

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>lists = [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">3</span>, <span style="color:#009900">'a'</span>, <span style="color:#006666">5</span>]
<span style="color:#006666">>>> </span>lists
[<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">3</span>, <span style="color:#009900">'a'</span>, <span style="color:#006666">5</span>]
<span style="color:#006666">>>> </span>lists[<span style="color:#006666">0</span>]
<span style="color:#006666">1</span>
<span style="color:#006666">>>> </span>lists[<span style="color:#006666">4</span>]
<span style="color:#006666">5</span>
<span style="color:#006666">>>> </span>lists[<span style="color:#006666">4</span>] = <span style="color:#009900">'b'</span>
<span style="color:#006666">>>> </span>lists[<span style="color:#006666">4</span>]
<span style="color:#009900">'b'</span>
<span style="color:#006666">>>> </span>lists.append(<span style="color:#009900">'c'</span>)
<span style="color:#006666">>>> </span>lists
[<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">3</span>, <span style="color:#009900">'a'</span>, <span style="color:#009900">'b'</span>, <span style="color:#009900">'c'</span>]</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注意:

  • Python允許在數組裏任意地防止數字或字符串
  • 數組下標是從0開始
  • append()函數可以向數組末尾追加新項

3.4.2 字典

字典:用花括號{}表示,裏面的項是成對出現,一個key對應一個value,key與value之間用冒號分隔,不同的項之間用逗號“,”分隔。

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>dicts = {<span style="color:#009900">"username"</span>:<span style="color:#009900">"zhangsan"</span>,<span style="color:#009900">'password'</span>:<span style="color:#006666">123456</span>}
<span style="color:#006666">>>> </span>dicts.keys()
[<span style="color:#009900">'username'</span>, <span style="color:#009900">'password'</span>]
<span style="color:#006666">>>> </span>dicts.values()
[<span style="color:#009900">'zhangsan'</span>, <span style="color:#006666">123456</span>]
<span style="color:#006666">>>> </span>dicts.items()
[(<span style="color:#009900">'username'</span>, <span style="color:#009900">'zhangsan'</span>), (<span style="color:#009900">'password'</span>, <span style="color:#006666">123456</span>)]
<span style="color:#006666">>>> </span><span style="color:#000088">for</span> k,v <span style="color:#000088">in</span> dicts.items():
    <span style="color:#000088">print</span> (<span style="color:#009900">"dicts keys is %r"</span> % k)
    <span style="color:#000088">print</span> (<span style="color:#009900">"dicts values is %r"</span> % v)


dicts keys <span style="color:#000088">is</span> <span style="color:#009900">'username'</span>
dicts values <span style="color:#000088">is</span> <span style="color:#009900">'zhangsan'</span>
dicts keys <span style="color:#000088">is</span> <span style="color:#009900">'password'</span>
dicts values <span style="color:#000088">is</span> <span style="color:#006666">123456</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

注意: Python規定一個字典中的key必須獨一無二,valuekey相同。

  • keys()函數:返回字典key的列表
  • values()函數:返回字典value的列表
  • items()函數:將所有的字典項以列表方式返回

按存放的順序輸出字典:

<span style="color:#000000"><code class="language-python"><span style="color:#880000"># 通過zip方法合併兩個List爲Dictionary</span>
<span style="color:#880000"># 遍歷會按原先的順序</span>
keys = [<span style="color:#009900">"b"</span>, <span style="color:#009900">"a"</span>, <span style="color:#009900">"c"</span>, <span style="color:#009900">"e"</span>, <span style="color:#009900">"d"</span>]
values = [<span style="color:#009900">"2"</span>, <span style="color:#009900">"1"</span>, <span style="color:#009900">"3"</span>, <span style="color:#009900">"5"</span>, <span style="color:#009900">"4"</span>]

<span style="color:#000088">for</span> key,value <span style="color:#000088">in</span> zip(keys, values):
    <span style="color:#000088">print</span> (key, value)</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

輸出結果: 
b 2 
a 1 
c 3 
e 5 
d 4

3.5 函數、類和方法

3.5.1 函數

Python通過def關鍵字來定義函數:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(a, b)</span>:
    <span style="color:#000088">print</span> (a + b)


<span style="color:#006666">>>> </span>add(<span style="color:#006666">3</span>, <span style="color:#006666">5</span>)
<span style="color:#006666">8</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通常函數不會直接打印結果,而是將結果通過return關鍵字返回:

<span style="color:#000000"><code class="language-python">>>><span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(a, b)</span>:
    <span style="color:#000088">return</span> a + b
>>>add(<span style="color:#006666">3</span>, <span style="color:#006666">5</span>)
<span style="color:#006666">8</span></code></span>
  • 1
  • 2
  • 3
  • 4

如果在調用函數時不想傳參,可以爲函數設置默認參數:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(a=<span style="color:#006666">1</span>, b=<span style="color:#006666">2</span>)</span>:
    <span style="color:#000088">return</span> a + b

<span style="color:#006666">>>> </span>add()
<span style="color:#006666">3</span>
<span style="color:#006666">>>> </span>add(<span style="color:#006666">3</span>, <span style="color:#006666">5</span>)
<span style="color:#006666">8</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.5.2 類和方法

在面向對象編程的世界裏,一切皆爲對象,抽象的一組對象就是類。

eg:汽車是一個類,而張三家的奇瑞汽車就是一個具體的對象。

Python使用class關鍵字來創建類。

<span style="color:#000000"><code class="language-python"><span style="color:#000088">class</span> <span style="color:#4f4f4f">A</span><span style="color:#4f4f4f">(object)</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a + b

count = A()
<span style="color:#000088">print</span> (count.add(<span style="color:#006666">3</span>, <span style="color:#006666">5</span>))</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

輸出結果爲:8

對上述代碼分析:

  • 創建一個類A(在Python 3中object爲所有類的基類,所有類在創建時默認繼承object,所以不聲明繼承object也可以)
  • 在類下面創建一個add()方法,注意,方法的第一個參數必須是存在的,一般習慣命名爲self,但在調用這個方法時不需要爲這個參數傳值

一般在創建類時會首先聲明初始化方法__init__(),注意,init的兩側是雙下劃線,當我們在調用該類時,可以用來進行一下初始化工作:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">class</span> <span style="color:#4f4f4f">A</span><span style="color:#4f4f4f">(object)</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">__init__</span><span style="color:#4f4f4f">(self, a, b)</span>:
        self.a = int(a)
        self.b = int(b)

    <span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(self)</span>:
        <span style="color:#000088">return</span> self.a + self.b

count = A(<span style="color:#009900">'4'</span>, <span style="color:#006666">5</span>)
<span style="color:#000088">print</span> (count.add())</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

輸出結果爲:9

對上述代碼分析:

  • 當調用A類時首先會執行它的__init__()方法,所以需要對其進行傳參
  • 初始化的工作就是將輸入的參數類型轉化爲int類型,保證程序容錯性
  • add()方法可以直接拿初始化方法的self.a和self.b兩個數進行計算
  • 所以在調用A類下面的add()方法時,不需要再傳參

Python中類的繼承:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">class</span> <span style="color:#4f4f4f">A</span><span style="color:#4f4f4f">()</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a + b

<span style="color:#000088">class</span> <span style="color:#4f4f4f">B</span><span style="color:#4f4f4f">(A)</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">sub</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a - b

<span style="color:#000088">print</span> (B().add(<span style="color:#006666">4</span>, <span style="color:#006666">5</span>))</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

輸出結果爲:9

對上述代碼分析:

  • 創建一個A類,在下面創建add()方法用於計算兩個參數相加
  • 創建一個B類,繼承A類,並且又繼續創建sub()方法用於計算兩個參數相減
  • 因爲B類繼承了A類,所以B類自然也擁有了add()方法,從而可以直接通過B類調用add()方法

3.6 模組

模組=類庫、模塊。

3.6.1 引用模塊

通過:import…或者from…import…的方式引用模塊,eg:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">import</span> time
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> time.ctime()
Mon Mar <span style="color:#006666">19</span> <span style="color:#006666">16</span>:<span style="color:#006666">20</span>:<span style="color:#006666">26</span> <span style="color:#006666">2018</span></code></span>
  • 1
  • 2
  • 3

如果確定只需要使用time下面的ctime()方法,還可以這樣引用,eg:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">from</span> time <span style="color:#000088">import</span> ctime
<span style="color:#006666">>>> </span><span style="color:#000088">print</span> ctime()
Mon Mar <span style="color:#006666">19</span> <span style="color:#006666">16</span>:<span style="color:#006666">22</span>:<span style="color:#006666">00</span> <span style="color:#006666">2018</span></code></span>
  • 1
  • 2
  • 3

現在使用時就不必告訴Python,ctime()方法是time模塊所提供的了。 
但是實際情況,可能是我們還需要使用time模塊下的sleep()方法,我們也可以這樣引入進來,但是還有其他方法呢,所以我們可以一次性把time模塊下的所有方法都引入進來,eg:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> time <span style="color:#000088">import</span> *

<span style="color:#000088">print</span> ctime()
<span style="color:#000088">print</span> <span style="color:#009900">"休眠兩秒"</span>
sleep(<span style="color:#006666">2</span>)
<span style="color:#000088">print</span> ctime()</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

最終輸出結果是:

<span style="color:#000000"><code class="language-shell"><span style="color:#000000">Mon</span> <span style="color:#000000">Mar</span> 19 16<span style="color:#000000">:46</span><span style="color:#000000">:22</span> 2018
休眠兩秒
<span style="color:#000000">Mon</span> <span style="color:#000000">Mar</span> 19 16<span style="color:#000000">:46</span><span style="color:#000000">:24</span> 2018</code></span>
  • 1
  • 2
  • 3

其中,星號(*),代表了模塊下的所有方法。通過導入模塊後,可以使用help查看模塊的doc,eg:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">import</span> time
help(time)</code></span>
  • 1
  • 2

pip所安裝的Python第三方庫或框架,都可以使用這種方式來查看。

3.6.2 模塊調用

一個軟件項目不可能把所有代碼都放在一個文件中實現,一般會按照一定規則在不同的目錄和文件中實現。

創建一個目錄project,並在目錄下創建兩個文件,結構如下:

<span style="color:#000000"><code><span style="color:#880000">project/</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">pub</span><span style="color:#009900">.</span><span style="color:#880000">py</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">count</span><span style="color:#009900">.</span><span style="color:#880000">py</span></code></span>
  • 1
  • 2
  • 3

在pub.py文件中創建add函數:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(a, b)</span>:
    <span style="color:#000088">return</span> a + b</code></span>
  • 1
  • 2

在count.py文件中調用pub.py文件中的add()函數:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> pub <span style="color:#000088">import</span> add

<span style="color:#000088">print</span> add(<span style="color:#006666">4</span>, <span style="color:#006666">5</span>)</code></span>
  • 1
  • 2
  • 3

輸出結果爲:9

這樣就實現了跨文件的函數調用。

注意: 以下情況會在你使用Python3.5版本中出現,在project目錄下,多了一個__pycache__/pub.cpython-35.pyc文件,它的作用是爲了提高模塊加載的速度,每個模塊都會在__pycache__文件夾中放置該模塊的預編譯模塊,命名爲module.version.pyc,version是模塊的預編譯版本編碼,通常會包含Python的版本號,例如在CPython發行版3.5中,pub.py文件的預編譯文件就是:__pycache__/pub.cpython-35.pyc。

3.6.3 跨目錄模塊調用

如果調用文件與被調用文件在一個目錄下面,那麼可以使用上面的方法,但是如果不在同一個目錄下,假設文件目錄結構如下:

<span style="color:#000000"><code><span style="color:#880000">project/</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">model/</span>
        <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">pub</span><span style="color:#009900">.</span><span style="color:#880000">py</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">count</span><span style="color:#009900">.</span><span style="color:#880000">py</span></code></span>
  • 1
  • 2
  • 3
  • 4

如果還還想在count.py中調用add方法,則需要將目錄的完整路徑補全,eg:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> model.pub <span style="color:#000088">import</span> add

<span style="color:#000088">print</span> add(<span style="color:#006666">4</span>, <span style="color:#006666">5</span>)</code></span>
  • 1
  • 2
  • 3

運行結果,依然是:9

3.6.4 進一步討論跨目錄模塊調用

目錄結構更加複雜的情況:

<span style="color:#000000"><code><span style="color:#880000">project/</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">model/</span>
        <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">count</span><span style="color:#009900">.</span><span style="color:#880000">py</span>
        <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">new_count</span><span style="color:#009900">.</span><span style="color:#880000">py</span>
    <span style="color:#880000">|</span><span style="color:#006666">-</span><span style="color:#006666">-</span><span style="color:#880000">test</span><span style="color:#009900">.</span><span style="color:#880000">py</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5

count.py代碼如下:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">class</span> <span style="color:#4f4f4f">A</span><span style="color:#4f4f4f">()</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">add</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a + b</code></span>
  • 1
  • 2
  • 3
  • 4

new_count.py代碼如下:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> count <span style="color:#000088">import</span> A

<span style="color:#000088">class</span> <span style="color:#4f4f4f">B</span><span style="color:#4f4f4f">(A)</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">sub</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a - b
resule = B().add(<span style="color:#006666">2</span>, <span style="color:#006666">5</span>)
<span style="color:#000088">print</span> resule</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

輸出結果:7

上述結果沒問題,接下來與model目錄平級創建test.py文件:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> model <span style="color:#000088">import</span> new_count

test = new_count()
test.add(<span style="color:#006666">2</span>, <span style="color:#006666">5</span>)</code></span>
  • 1
  • 2
  • 3
  • 4

輸出結果,會出現:ImportError: No module named 'count'

通過提示信息,在new_count.py文件中,找不到“count”模塊,可剛纔在執行new_count.py時是可以正常運行的,那麼,要想弄清楚錯誤的原因,首先要知道當Python執行import時到底做了哪些操作?

重點:

當Python在執行import語句時,執行了如下操作:

  • 第1步:創建一個新的module對象(它可能包含多個module);

  • 第2步:把這個module對象插到sys.module中;

  • 第3步:裝載module的代碼(如果需要,則必須先編譯);

  • 第4步:執行新的module中對應的代碼;

在執行第3步的時候,首先需要找到module程序所在的位置,搜索的順序是:

當前路徑(以及從當前目錄指定的sys.path),PythonPATH,再後是Python安裝時設置的相關的默認路徑。正因爲存在這樣的順序,所以如果當前路徑或PythonPATH中存在於標準module同樣的module,則會覆蓋標準module。也就是說,如果當前目錄下存在xml.py,那麼在執行import xml時導入的就是當前目錄下的module,而不是系統標準的xml。

瞭解了這些後,我們就可以先構建一個package,以普通module的方式導入,這樣即可直接訪問此package中各個module,注意,Python2中的package必須包含一個__init__.py的文件。

所以上面問題的錯誤原因就是:

站在new_count.py的位置,執行from count import A,可查看當前目錄下是否存在“count”名字的文件或目錄,是可以找到的,但是站在test.py的位置,執行from count import A時,在當前目錄下是找不到“count”名字的文件或目錄的,所以拋出異常。

解決辦法:

最簡單的辦法就是將導入方法修改爲from .count import A,在“count”前面加個點,用來告訴程序count是相對於new_content.py的一個導入。

上面解決辦法引入的新的問題:

修改new_count.py代碼如下:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> .count <span style="color:#000088">import</span> A

<span style="color:#000088">class</span> <span style="color:#4f4f4f">B</span><span style="color:#4f4f4f">(A)</span>:

    <span style="color:#000088">def</span> <span style="color:#009900">sub</span><span style="color:#4f4f4f">(self, a, b)</span>:
        <span style="color:#000088">return</span> a - b

result = B().add(<span style="color:#006666">2</span>, <span style="color:#006666">5</span>)
<span style="color:#000088">print</span> result</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

當再次執行test.py代碼時,出現了新的錯誤:

<span style="color:#000000"><code class="language-syslog">Traceback (most recent <span style="color:#000088">call</span> <span style="color:#000088">last</span>):
  File <span style="color:#009900">"/tmp/project/model/new_count.py"</span>, line <span style="color:#006666">1</span>, <span style="color:#000088">in</span> <<span style="color:#000088">module</span>>
    <span style="color:#000088">from</span> .<span style="color:#009900">count</span> import A
[Finished <span style="color:#000088">in</span> <span style="color:#006666">0.1</span>s <span style="color:#000088">with</span> exit code <span style="color:#006666">1</span>]SystemError: Parent <span style="color:#000088">module</span> <span style="color:#009900">''</span> <span style="color:#000088">not</span> loaded, cannot perform <span style="color:#000088">relative</span> import</code></span>
  • 1
  • 2
  • 3
  • 4

這句話的意思是:“未加載父模塊,不能執行相對導入”。

解決辦法:

需要將導入模塊所在目錄添加到系統環境變量PATH目錄下纔可以。

修改test.py的代碼:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">import</span> sys
sys.path.append(<span style="color:#009900">"./model"</span>)  <span style="color:#880000">#將model目錄添加到系統環境變量path下</span>
<span style="color:#000088">from</span> model <span style="color:#000088">import</span> new_count

test = new_count()
test.add(<span style="color:#006666">2</span>, <span style="color:#006666">5</span>)</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

輸出結果:7,注意如果是python2版本需要在model目錄下創建init文件才行。

3.7 異常

Python用異常對象(exception object)來表示異常情況。遇到錯誤後,會引發異常,如果異常對象並未被處理或者捕捉,則程序就會用所謂的回溯(Traceback,一種錯誤信息)來終止執行。

3.7.1 認識異常

看下面的代碼:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span>open(<span style="color:#009900">"abc.txt"</span>, <span style="color:#009900">'r'</span>)
Traceback (most recent call last):
  File <span style="color:#009900">"<stdin>"</span>, line <span style="color:#006666">1</span>, <span style="color:#000088">in</span> <module>
IOError: [Errno <span style="color:#006666">2</span>] No such file <span style="color:#000088">or</span> directory: <span style="color:#009900">'abc.txt'</span></code></span>
  • 1
  • 2
  • 3
  • 4

錯誤很明顯,我們根本沒創建這個文件,自然也無法open操作。我們可以視線捕捉這個異常:Python通過try…except…語句來接收並處理這個異常。

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">try</span>:
<span style="color:#006666">... </span>    open(<span style="color:#009900">"abc.txt"</span>, <span style="color:#009900">"r"</span>)
<span style="color:#006666">... </span><span style="color:#000088">except</span> IOError:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> <span style="color:#009900">"異常了"</span>
<span style="color:#006666">... </span>
異常了</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意: 我們這裏使用的仍然是Python2版本,所以和書中的Python3版本略有不同,以下都是按Python2版本進行演示的。

再來看下面的例子:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">try</span>:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> aa
<span style="color:#006666">... </span><span style="color:#000088">except</span> IOError:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> <span style="color:#009900">"異常了"</span>
<span style="color:#006666">... </span>
Traceback (most recent call last):
  File <span style="color:#009900">"<stdin>"</span>, line <span style="color:#006666">2</span>, <span style="color:#000088">in</span> <module>
NameError: name <span style="color:#009900">'aa'</span> <span style="color:#000088">is</span> <span style="color:#000088">not</span> defined</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的例子,雖然捕捉異常,但是由於捕捉的異常和實際異常的錯誤類型並不相符,所以導致失效。

只需要更換一個正確的接收異常的類型就可以了:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">try</span>:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> aa
<span style="color:#006666">... </span><span style="color:#000088">except</span> NameError:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> <span style="color:#009900">"異常了"</span>
<span style="color:#006666">... </span>
異常了</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

那麼,程序是怎麼拋出不同類型的錯誤呢?

異常的拋出機制:

  1. 如果在運行時發生異常,則解釋器會查找相應的處理語句(稱爲handler);
  2. 如果在當前函數裏沒有找到的話,則它會將異常傳遞給上層的調用函數,看看那裏能不能處理;
  3. 如果在最外層(全局main)還是沒有找到的話,那麼解釋器就會退出,同時打印出Traceback,以便讓用戶找到錯誤產生的原因。

注意: 異常不一定等於錯誤,有時候它只是一個警告,有時候它只是一個終止信號,例如退出循環等。

Python中所有異常都集成Exception,所以可以使用它來接收所有類型的異常:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">try</span>:
    open(<span style="color:#009900">"abc.txt"</span>, <span style="color:#009900">"r"</span>)
<span style="color:#000088">except</span> Exception:
    <span style="color:#000088">print</span> <span style="color:#009900">"異常了"</span>

異常了</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

從Python 2.5之後,所有的異常類都有了新的基類BaseException,Exception同樣也繼承自BaseException,所以我們可以使用BaseException來接收所有類型的異常:

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">try</span>:
<span style="color:#006666">... </span>    open(<span style="color:#009900">"abc.txt"</span>, <span style="color:#009900">"r"</span>)
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> aa
<span style="color:#006666">... </span><span style="color:#000088">except</span> BaseException:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> <span style="color:#009900">"異常了"</span>
<span style="color:#006666">... </span>
異常了</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

對於這個例子來說,只要其中一行出現了異常就會打印出異常信息,但是如何才能準確知道是哪一行代碼引起的異常呢,又如何讓Python直接告訴我們異常的原因呢?

<span style="color:#000000"><code class="language-python"><span style="color:#006666">>>> </span><span style="color:#000088">try</span>:
<span style="color:#006666">... </span>    open(<span style="color:#009900">"abc.txt"</span>, <span style="color:#009900">"r"</span>)
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> aa
<span style="color:#006666">... </span><span style="color:#000088">except</span> BaseException, e:
<span style="color:#006666">... </span>    <span style="color:#000088">print</span> e
<span style="color:#006666">... </span>
[Errno <span style="color:#006666">2</span>] No such file <span style="color:#000088">or</span> directory: <span style="color:#009900">'abc.txt'</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這樣就可以打印出異常的詳細信息了。

注意: Python 2中使用“, e”這種方式來捕捉異常詳細信息,而Python 3中使用“as msg”的方式,這是兩者的區別。

Python常見的異常

異常 描述
BaseException 新的所有異常類的基類
Exception 所有異常類的基類,但繼承BaseException類
AssertionError assert語句失敗
FileNotFoundError 試圖打開一個不存在的文件或目錄
AttributeError 試圖訪問的對象沒有屬性
OSError 當系統函數返回一個系統相關的錯誤,包括I/O故障,如“找不到文件”或“磁盤已滿”時,引發此異常
NameError 使用一個還未賦值對象的變量
IndexError 當一個序列超出了範圍
SyntaxError 當解析器遇到一個語法錯誤時引發
KeyboardInterrupt Ctrl+C被按下,程序被強行終止
TypeError 傳入的對象類型與要求不符

3.7.2 更多異常用法

異常的更多用法:try...except...else

<span style="color:#000000"><code class="language-python"><span style="color:#000088">try</span>:
    aa = <span style="color:#009900">"異常測試:"</span>
    <span style="color:#000088">print</span> aa
<span style="color:#000088">except</span> Exception <span style="color:#000088">as</span> msg:
    <span style="color:#000088">print</span> msg
<span style="color:#000088">else</span>:
    <span style="color:#000088">print</span> <span style="color:#009900">"沒有異常!"</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

輸出結果:

<span style="color:#000000"><code>異常測試:
沒有異常!</code></span>
  • 1
  • 2

上面代碼是因爲沒有異常所以執行了else,但是例如文件的關閉、鎖的釋放、把數據庫連接返還給連接池等操作,這些操作無論是否異常都希望可以被執行,就需要用到:try...except...finally...

<span style="color:#000000"><code class="language-python"><span style="color:#000088">try</span>:
    <span style="color:#000088">print</span> aa
<span style="color:#000088">except</span> Exception <span style="color:#000088">as</span> e:
    <span style="color:#000088">print</span> e
<span style="color:#000088">finally</span>:
    <span style="color:#000088">print</span> <span style="color:#009900">"不管是否異常,我都會被執行。"</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

輸出結果:

<span style="color:#000000"><code>name <span style="color:#009900">'aa'</span> is <span style="color:#000088">not</span> <span style="color:#000088">defined</span>
不管是否異常,我都會被執行。</code></span>
  • 1
  • 2

修改上述代碼,定義aa變量:

<span style="color:#000000"><code class="language-python"><span style="color:#000088">try</span>:
    aa = <span style="color:#009900">"異常測試:"</span>
    <span style="color:#000088">print</span> aa
<span style="color:#000088">except</span> Exception <span style="color:#000088">as</span> e:
    <span style="color:#000088">print</span> e
<span style="color:#000088">finally</span>:
    <span style="color:#000088">print</span> <span style="color:#009900">"不管是否異常,我都會被執行。"</span></code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

輸出結果:

<span style="color:#000000"><code class="language-python">異常測試:
不管是否異常,我都會被執行。</code></span>
  • 1
  • 2

3.7.3 拋出異常

print方法只是打印異常,而raise方法可以拋出一個異常信息。

<span style="color:#000000"><code class="language-python"><span style="color:#000088">from</span> random <span style="color:#000088">import</span> randint

<span style="color:#880000"># 生成一個1到9之間的隨機整數</span>
number = randint(<span style="color:#006666">1</span>, <span style="color:#006666">9</span>)

<span style="color:#000088">if</span> number % <span style="color:#006666">2</span> == <span style="color:#006666">0</span>:
    <span style="color:#000088">raise</span> NameError(<span style="color:#009900">"%d is even"</span> % number)
<span style="color:#000088">else</span>:
    <span style="color:#000088">raise</span> NameError(<span style="color:#009900">"%d is odd"</span> % number)</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

輸出結果:

<span style="color:#000000"><code class="language-python">Traceback (most recent call last):
  File <span style="color:#009900">"<stdin>"</span>, line <span style="color:#006666">4</span>, <span style="color:#000088">in</span> <module>
NameError: <span style="color:#006666">3</span> <span style="color:#000088">is</span> odd</code></span>
  • 1
  • 2
  • 3

判斷奇偶數與NameError之間沒有任何關係,這裏只是爲了演示如何通過raise方法拋出各種類型的異常。

注意: raise只能使用Python中所提供的異常類,如果自定義一個abcError,會提示錯誤abcError未定義。

總結

本章內容只是Python語法的入門的入門,如果想要開始後面的教程,還需要有Python基礎,而最佳快速入門的就是《笨方法學Python》了,有興趣的同學可以搜索並學習。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章