Python3學習筆記04-循環、函數、面向對象

##1、循環 ###一、for循環 for循環須要預先設定好循環的次數(n),而後執行隸屬於for的語句n次。python

基本構造是:web

for 元素 in 序列: 
    statement

舉例來講,咱們編輯一個叫forDemo.py的文件django

for a in [3, 4.5, 'we', 'love', 'u']:
    print a

這個循環就是每次從表[3,4.4,'life'] 中取出一個元素(回憶:表是一種序列),而後將這個元素賦值給a,以後執行隸屬於for的操做(print)。編程

輸入圖片說明

介紹一個新的Python函數range(),來幫助你創建表。多線程

idx = range(5) print idx 能夠看到idx是[0,1,2,3,4]app

這個函數的功能是新建一個表。這個表的元素都是整數,從0開始,下一個元素比前一個大1, 直到函數中所寫的上限 (不包括該上限自己)函數

(關於range(),還有豐富用法,有興趣能夠查閱, Python 3中, range()用法有變化,見評論區)學習

舉例this

for a in range(10):
    print a**2

打印結果:操作系統

輸入圖片說明

###二、while循環

while的用法是:

while 條件:
    statement

while會不停地循環執行隸屬於它的語句,直到條件爲假(False)

舉例

while i < 10:
    print i
    i = i + 1

###三、中斷循環

continue # 在循環的某一次執行中,若是遇到continue, 那麼跳過這一次執行,進行下一次的操做
break # 中止執行整個循環

for i in range(10):
    if i == 2: 
        continue
    print i

當循環執行到i = 2的時候,if條件成立,觸發continue, 跳過本次執行(不執行print),繼續進行下一次執行(i = 3)。

for i in range(10):
    if i == 2:        
        break
    print i

當循環執行到i = 2的時候,if條件成立,觸發break, 整個循環中止。

##2、函數 函數最重要的目的是方便咱們重複使用相同的一段程序。

將一些操做隸屬於一個函數,之後你想實現相同的操做的時候,只用調用函數名就能夠,而不須要重複敲全部的語句。

###一、函數的定義 首先,咱們要定義一個函數, 以說明這個函數的功能。

def square_sum(a,b):
    c = a**2 + b**2
    return c

這個函數的功能是求兩個數的平方和。

首先,def,這個關鍵字通知python:我在定義一個函數。square_sum是函數名。

括號中的a, b是函數的參數,是對函數的輸入。參數能夠有多個,也能夠徹底沒有(但括號要保留)。

咱們已經在循環和選擇中見過冒號和縮進來表示的隸屬關係。

  • c = a2 + b2 # 這一句是函數內部進行的運算

  • return c # 返回c的值,也就是輸出的功能。Python的函數容許不返回值,也就是不用return。

  • return能夠返回多個值,以逗號分隔。至關於返回一個tuple(定值表)。

  • return a,b,c # 至關於 return (a,b,c) 在python中#表明註釋,編譯器將跳過#後的內容。 在Python中,當程序執行到return的時候,程序將中止執行函數內餘下的語句。return並非必須的,當沒有return, 或者return後面沒有返回值時,函數將自動返回None。None是Python中的一個特別的數據類型,用來表示什麼都沒有,至關於C中的NULL。None多用於關鍵字參數傳遞的默認值。

###二、函數調用和參數傳遞 定義過函數後,就能夠在後面程序中使用這一函數:

print square_sum(3,4)
Python經過位置,知道3對應的是函數定義中的第一個參數a, 4對應第二個參數b,而後把參數傳遞給函數square_sum。

(Python有豐富的參數傳遞方式,還有關鍵字傳遞、表傳遞、字典傳遞等,基礎教程將只涉及位置傳遞) 函數通過運算,返回值13, 這個13被print打印出來。

輸入圖片說明

咱們再看下面兩個例子:

a = 1

def change_integer(a):
    a = a + 1
    return a

print change_integer(a)      #注意觀察結果
print a      #注意觀察結果

#===(Python中 "#" 後面跟的內容是註釋,不執行 )

b = [1,2,3]

def change_list(b):
    b[0] = b[0] + 1
    return b

print change_list(b)      #注意觀察結果
print b      #注意觀察結果

第一個例子,咱們將一個整數變量傳遞給函數,函數對它進行操做,但原整數變量a不發生變化。

第二個例子,咱們將一個表傳遞給函數,函數進行操做,原來的表b發生變化。

對於基本數據類型的變量,變量傳遞給函數後,函數會在內存中複製一個新的變量,從而不影響原來的變量。(咱們稱此爲值傳遞)

可是對於表來講,表傳遞給函數的是一個指針,指針指向序列在內存中的位置,在函數中對錶的操做將在原有內存中進行,從而影響原有變量。 (咱們稱此爲指針傳遞),指針是C/C++語言中的重要概念,有關指針的概念能夠到網上搜索相關資料。

##3、面向對象的基本概念 Python使用類(class)和對象(object),進行面向對象(object-oriented programming,簡稱OOP)的編程。

面向對象的最主要目的是提升程序的重複使用性。咱們這麼早切入面向對象編程的緣由是,Python的整個概念是基於對象的。瞭解OOP是進一步學習Python的關鍵。

下面是對面向對象的一種理解,基於分類。

###一、相近對象,歸爲類 在人類認知中,會根據屬性相近把東西歸類,而且給類別命名。好比說,鳥類的共同屬性是有羽毛,經過產卵生育後代。任何一隻特別的鳥都在鳥類的原型基礎上的。

面向對象就是模擬了以上人類認知過程。在Python語言,爲了聽起來酷,咱們把上面說的「東西」稱爲對象(object)。

先定義鳥類:

class Bird(object):
    have_feather = True   # 注意:這裏的True區分大小寫,首字母必須大寫,不然報錯
    way_of_reproduction  = 'egg'

咱們定義了一個類別(class),就是鳥(Bird)。在隸屬於這個類比的語句塊中,咱們定義了兩個變量,一個是有羽毛(have_feather),一個是生殖方式(way_of_reproduction),這兩個變量對應咱們剛纔說的屬性(attribute)。咱們暫時先不說明括號以及其中的內容,記爲問題1。

假設我養了一隻小雞,叫summer。它是個對象,且屬於鳥類。使用前面定義的類:

summer = Bird()
print summer.way_of_reproduction

經過第一句建立對象,並說明summer是類別鳥中的一個對象,summer就有了鳥的類屬性,對屬性的引用是經過 對象.屬性(object.attribute) 的形式實現的。

可憐的summer,你就是個有毛產的蛋貨,好不精緻。

###二、動做 平常認知中,咱們在經過屬性識別類別的時候,有時根據這個東西能作什麼事情來區分類別。好比說,鳥會移動。這樣,鳥就和房屋的類別區分開了。這些動做會帶來必定的結果,好比移動致使位置的變化。

這樣的一些「行爲」屬性爲方法(method)。Python中經過在類的內部定義函數,來講明方法。

class Bird(object):
    have_feather = True
    way_of_reproduction = 'egg'
    def move(self, dx, dy):
        position = [0,0]
        position[0] = position[0] + dx
        position[1] = position[1] + dy
        return position

summer = Bird()
print 'after move:',summer.move(5,8)

咱們從新定義了鳥這個類別。鳥新增一個方法屬性,就是表示移動的方法move。(我認可這個方法很傻,你能夠在看過下一講以後定義個有趣些的方法)

(它的參數中有一個self,它是爲了方便咱們引用對象自身。方法的第一個參數必須是self,不管是否用到。有關self的內容稍後介紹) 另外兩個參數,dx, dy表示在x、y兩個方向移動的距離。move方法會最終返回運算過的position。

在最後調用move方法的時候,咱們只傳遞了dx和dy兩個參數,不須要傳遞self參數(由於self只是爲了內部使用)

個人summer能夠跑了。 ###三、子類 類別自己還能夠進一步細分紅子類。

好比說,鳥類能夠進一步分紅雞,大雁,黃鸝。

在OOP中,咱們經過繼承(inheritance)來表達上述概念。

class Chicken(Bird):
    way_of_move = 'walk'
    possible_in_KFC = True

class Oriole(Bird):
    way_of_move = 'fly'
    possible_in_KFC = False

summer = Chicken()
print summer.have_feather
print summer.move(5,8)

新定義的雞(Chicken)類的,增長了兩個屬性:移動方式(way_of_move),可能在KFC找到(possible_in_KFC)。

在類定義時,括號裏爲了Bird。這說明,Chicken是屬於鳥類(Bird)的一個子類,即Chicken繼承自Bird。天然而然,Bird就是Chicken的父類。Chicken將享有Bird的全部屬性。儘管我只聲明瞭summer是雞類,它經過繼承享有了父類的屬性(不管是變量屬性have_feather仍是方法屬性move)

新定義的黃鸝(Oriole)類,一樣繼承自鳥類。在建立一個黃鸝對象時,該對象自動擁有鳥類的屬性。

經過繼承製度,咱們能夠減小程序中的重複信息和重複語句。若是咱們分別定義兩個類,而不繼承自鳥類,就必須把鳥類的屬性分別輸入到雞類和黃鸝類的定義中。整個過程會變得繁瑣,所以,面向對象提升了程序的可重複使用性。

(回到問題1, 括號中的object,當括號中爲object時,說明這個類沒有父類(到頭了))

將各類各樣的東西分類,從而瞭解世界,從人類祖先開始,咱們就在練習了這個認知過程,面向對象是符合人類思惟習慣的。所謂面向過程,也就是執行完一個語句再執行下一個,更多的是機器思惟。經過面向對象的編程,咱們能夠更方便的表達思惟中的複雜想法。

##4、面向對象的進一步拓展 ###一、調用類的其它信息 剛纔提到,在定義方法時,必須有self這一參數。這個參數表示某個對象。對象擁有類的全部性質(若是學習過Java 或C++等語言的便會知道,self至關於this),那麼咱們能夠經過self,調用類屬性。

class Human(object):
    laugh = 'hahahaha'
    def show_laugh(self):
        print self.laugh
    def laugh_100th(self):
        for i in range(100):
            self.show_laugh()

li_lei = Human()          
li_lei.laugh_100th()

這裏有一個類屬性laugh。在方法show_laugh()中,經過self.laugh,調用了該屬性的值。

還能夠用相同的方式調用其它方法。方法show_laugh(),在方法laugh_100th中()被調用。

在對象中對類屬性進行賦值的時候,實際上會在對象定義的做用域中添加一個屬性(若是還不存在的話),並不會影響到相應類中定義的同名類屬性。但若是是修改類屬性的內容(好比類屬性是個字典,修改字典內容)時會影響到全部對象實例,由於這個類屬性的內容是共享的。

###二、init() 方法 init() 是一個特殊方法(special method)。Python有一些特殊方法。Python會特殊的對待它們。特殊方法的特色是名字先後有兩個下劃線

若是你在類中定義了**init()** 這個方法,建立對象時,Python會自動調用這個方法。這個過程也叫初始化

class happyBird(Bird): def init(self,more_words): print 'We are happy birds.',more_words

summer = happyBird('Happy,Happy!') 這裏繼承了Bird類。屏幕上打印:

We are happy birds.Happy,Happy!

咱們看到,儘管咱們只是建立了summer對象,但__init__() 方法被自動調用了。最後一行的語句(summer = happyBird...)先建立了對象,而後執行:

summer.__init__(more_words)

'Happy,Happy!' 被傳遞給了__init__() 的參數more_words

###三、對象的性質 咱們講到了許多屬性,但這些屬性是類的屬性。全部屬於該類的對象會共享這些屬性。好比說,鳥都有羽毛,雞都不會飛。

在一些狀況下,咱們定義對象的性質,用於記錄該對象的特別信息。好比說,人這個類。性別是某我的的一個性質,不是全部的人類都是男,或者都是女。這個性質的值隨着對象的不一樣而不一樣。李雷是人類的一個對象,性別是男;韓美美也是人類的一個對象,性別是女。

當定義類的方法時,必需要傳遞一個self的參數。這個參數指代的就是類的一個對象。咱們能夠經過操縱self,來修改某個對象的性質。好比用類來新建一個對象,即下面例子中的li_lei, 那麼li_lei就被self表示。咱們經過賦值給self.attribute,給li_lei這一對象增長一些性質,好比說性別的男女。self會傳遞給各個方法。在方法內部,能夠經過引用self.attribute,查詢或修改對象的性質。

這樣,在類屬性的以外,又給每一個對象增添了各自特點的性質,從而能描述多樣的世界。

class Human(object):
    def __init__(self, input_gender):
        self.gender = input_gender
    def printGender(self):
        print self.gender

li_lei = Human('male') # 這裏,'male'做爲參數傳遞給__init__()方法的input_gender變量。
print li_lei.gender   #這一行結果與下一行對比
li_lei.printGender()   #這一行結果與上一行對比

在初始化中,將參數input_gender,賦值給對象的性質,即self.gender。

li_lei擁有了對象性質gender。gender不是一個類屬性。Python在創建了li_lei這一對象以後,使用li_lei.gender這一對象性質,專門儲存屬於對象li_lei的特有信息。

對象的性質也能夠被其它方法調用,調用方法與類屬性的調用類似,正如在printGender()方法中的調用。

結果打印:

輸入圖片說明

##5、反過頭來看看 從最初的「Hello World」,走到面向對象。該回過頭來看看,教程中是否遺漏了什麼。

咱們以前提到一句話,"Everything is Object". 那麼咱們就深刻體驗一下這句話。

須要先要介紹兩個內置函數:dir()help()

dir()用來查詢一個類或者對象全部屬性。你能夠嘗試一下:

>>>print dir(list)

help()用來查詢的說明文檔。你能夠嘗試一下:

>>>print help(list)

(list是Python內置的一個類,對應於咱們以前講解過的列表) ###一、list是一個類 在上面以及看到,表是Python已經定義好的一個類。當咱們新建一個表時,好比:

>>>nl = [1,2,5,3,5]

實際上,nl是類list的一個對象。

實驗一些list的方法:

>>>print nl.count(5)       # 計數,看總共有多少個5

>>>print nl.index(3)       # 查詢 nl 的第一個3的下標

>>>nl.append(6)            # 在 nl 的最後增添一個新元素6

>>>nl.sort()               # 對nl的元素排序

>>>print nl.pop()          # 從nl中去除最後一個元素,並將該元素返回。

>>>nl.remove(2)            # 從nl中去除第一個2

>>>nl.insert(0,9)          # 在下標爲0的位置插入9

總之,list是一個類。每一個列表都屬於該類。

Python補充中有list經常使用方法的附錄。

二、運算符是特殊方法 使用dir(list)的時候,能看到一個屬性,是add()。從形式上看是特殊方法(下劃線,下劃線)。它特殊在哪呢?

輸入圖片說明

這個方法定義了"+"運算符對於list對象的意義,兩個list的對象相加時,會進行的操做。

>>>print [1,2,3] + [5,6,9]
[1, 2, 3, 5, 6, 9]

運算符,好比+, -, >, <, 以及下標引用[start:end]等等,從根本上都是定義在類內部的方法。

嘗試一下:

>>>print [1,2,3] - [3,4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'list' and 'list'

會有錯誤信息,說明該運算符「-」沒有定義。如今咱們繼承list類,添加對"-"的定義:

class superList(list):
    def __sub__(self, b):
        a = self[:]     # 這裏,self是supeList的對象。因爲superList繼承於list,它能夠利用和list[:]相同的引用方法來表示整個對象。
        b = b[:]        
        while len(b) > 0:
            element_b = b.pop()
            if element_b in a:
                a.remove(element_b)
        return a

print superList([1,2,3]) - superList([3,4]) 內置函數**len()**用來返回list所包含的元素的總數。內置函數__sub__() 定義了「-」的操做:從第一個表中去掉第二個表中出現的元素。若是__sub__() 已經在父類中定義,你又在子類中定義了,那麼子類的對象會參考子類的定義,而不會載入父類的定義。任何其餘的屬性也是這樣。

(教程最後也會給出一個特殊方法的清單) 定義運算符對於複雜的對象很是有用。舉例來講,人類有多個屬性,好比姓名,年齡和身高。咱們能夠把人類的比較(>, <, =)定義成只看年齡。這樣就能夠根據本身的目的,將本來不存在的運算增長在對象上了。

###三、下一步 但願你已經對Python有了一個基本瞭解。你可能躍躍欲試,要寫一些程序練習一下。這會對你頗有好處。

可是,Python的強大很大一部分緣由在於,它提供有不少已經寫好的,能夠現成用的對象。咱們已經看到了內置的好比說list,還有tuple等等。它們用起來很方便。在Python的標準庫裏,還有大量能夠用於操做系統互動,Internet開發,多線程,文本處理的對象。而在全部的這些的這些的基礎上,又有不少外部的庫包,定義了更豐富的對象,好比numpy, tkinter, django等用於科學計算,GUI開發,web開發的庫,定義了各類各樣的對象。對於通常用戶來講,使用這些庫,要比本身去從頭開始容易得多。咱們要開始攀登巨人的肩膀了。

謝謝你的關注,

歡迎來到Python的世界。

相關文章
相關標籤/搜索