python基礎總結

    python技術網站:

廖雪峯的官網:http://www.liaoxuefeng.com/

python example 1 from github :https://github.com/adaptives/python-examples

python data science introductory : https://github.com/katychuang/python-data-sci-basics

the python tutorial : https://docs.python.org/3.3/tutorial/index.html

python資料彙集 :http://www.cnblogs.com/lanxuezaipiao/p/3543658.html

python idiom : http://safehammad.com/downloads/python-idioms-2014-01-16.pdf

full stack python : http://www.fullstackpython.com/

the elements of python style : https://github.com/amontalenti/elements-of-python-style#follow-most-pep8-guidelines

how to develop quality python code : https://districtdatalabs.silvrback.com/how-to-develop-quality-python-code

a good book : https://pymotw.com/2/contents.html

another good book : https://pymotw.com/3/

awesome python : https://github.com/vinta/awesome-python

awesome-python.com  : http://awesome-python.com/

easy python : http://easy-python.readthedocs.io/en/latest/

a web book : http://anandology.com/python-practice-book/index.html

udacity python basic : https://cn.udacity.com/course/programming-foundations-with-python--ud036

an amazing python challenge website : http://www.pythonchallenge.com/


Python的開發環境從官網上下載二進制文件進行安裝,即得到python解釋器、編譯器、內置對象和擴展模塊的集合。並且自帶了IDLE和python manual document。集成開發環境選用PyCharm,界面非常類似於google的AS,練習的時候使用idle。

python是一種面向對象的超高級語言,解釋執行,動態語言,是我第一門接觸的動態語言。支持任意大小的整數、複數、浮點數、雙引號或單引號括起來的字符串、轉義字符、布爾值bool、與and或or非not、空None、列表、字典、元組、集合、函數、自定義數據結構。共30個關鍵字,多種運算符。支持變量賦值,所有數據都是對象,支持常量。最開始很特殊的python不以{}來規定界限和模塊而是縮進,標準是一個模塊中縮進4個空格。函數採用傳遞對象引用的方式,既不用值傳遞也不用引用傳遞的方式。在python中一切都是對象,之前還看到過有人抨擊java不是徹底的面向對象因爲java的數據不是對象,覺得很扯淡,可是python裏面任何數據都是對象,這真是徹底的面向對象。

在最新的python3版本中字符串採用Unicode編碼,python文件開頭聲明的_*_coding:xxx_*_告訴python解釋器怎麼去解碼錶示源代碼的字符。只有聲明和計算機編碼的方式一致的時候,纔不會出錯。Unicode編碼方式中包括utf-8、utf-16和utf-32種類,utf-8採用變長方式1~4個字節表示一個字符,以達到縮小存儲空間的目的。對字符串使用encode(type)和decode(type)函數可以將字符串用指定的編碼字符集進行編碼輸出和解碼輸出,使用len()方法輸出字符個數。會由字符和字節編碼轉換,兩者採用相同的字符集纔不會出現亂碼,第一python源文件使用_*_coding:utf-8_*_聲明使得計算機執行的使用utf-8,第二編輯器採用utf-8存儲。格式化輸出的時候使用%,有%s、%d、%f、%x。


Python支持列表,列表類型list是一種有序的集合,隨時添加和刪除元素。使用方式類似於數組,但是可以放置不同類型的數據在同一個list中,使用[ ]進行特定位置的元素索引,從0開始,使用-1直接索引最後一個。


python支持元組,元組tuple不能改變,可以索引。但是tuple裏面嵌套了list則list是可以改變內容的。tuple的每個元素,指向永遠不變,可是指向的內容實際上可以變。即指向'a',就不能改成指向'b',指向一個list,就不能改成指向其他對象。


簡單判斷if else elif。input函數返回的是str字符串類型的數據。

Python的循環有兩種,一種是for...in循環,依次把list或tuple中的每個元素迭代出來。for x in ...循環就是把每個元素代入變量x,然後執行縮進塊的語句。range(x)可以生成0~x-1的list。第二種循環是while循環,只要條件滿足,就不斷循環,條件不滿足時退出循環。存在break和continue使用。
dict字典,採用KV存儲,即哈希存儲,採取覆蓋原則。涉及in查詢關鍵字是否在字典中、get函數得到K對應的V、刪除函數pop(key)。和list比較,dict有以下幾個特點:查找和插入的速度極快,不會隨着key的增加而變慢;需要佔用大量的內存,內存浪費多。而list相反:查找和插入的時間隨着元素的增加而增加;佔用空間小,浪費內存很少。dict高速查找。dict的key必須是不可變對象。在Python中,字符串、整數等都是不可變的,因此,可以放心地作爲key。而list是可變的,就不能作爲key。
集合set中存儲key,不能重複。要創建一個set,需要提供一個list作爲輸入集合s = set([1, 2, 3]),數據無序,重複數據自動過濾。涉及add函數、remove函數、交操作&、並操作|。對不可變對象的操作是在創建新的對象返回。


在Python中,定義一個函數要使用def語句,依次寫出函數名、括號、括號中的參數和冒號:,然後,在縮進塊中編寫函數體,函數的返回值用return語句返回。如果沒有return語句,函數執行完畢後也會返回結果,只是結果爲None。如果想定義一個什麼事也不做的空函數,可以用pass語句。可以添加數據類型檢查函數isinstance()來檢查傳參類型。

一個函數可以返回多個值,返回時使用return nx, ny,調用函數接受時使用x, y = move(100, 100, 60, math.pi / 6),實際上返回的是tuple,使用也給變量接受也可以,只不過該變量意爲元組。


除了正常定義的必選參數外,還可以使用默認參數x=9、可變參數和關鍵字參數。默認參數中必選參數在前,默認參數在後,否則Python的解釋器會報錯。默認參數必須指向不變對象。可變參數就是傳入的參數個數是可變的,其形參形式爲*numbers,函數內部接受的numbers是一個tuple。可變參數允許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝爲一個tuple。而關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝爲一個dict。調用者仍可以傳入不受限制的關鍵字參數,函數內部可以進行參數檢查。如果要限制關鍵字參數的名字,就可以用命名關鍵字參數,*後面的參數被視爲命名關鍵字參數。參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。關鍵字參數可以擴展函數的功能。


Python提供了其他語言沒有提供的高級功能,例如slice切片。slice用於指定搜索範圍的查找,切片用於list、tuple、dict數據結構。L[0:2]說明從0開始到2爲止且不包括位置2,以供2個元素取出,L[-2:-1]從倒數第二位置至最後一個索引位置不包括最後一個數據一個1個即倒數第二個。


python利用for ...in...進行迭代循環,迭代對象可以是list、tuple、dict、str。python極其靈活強大,對dict迭代默認迭代key,使用for value in d.values()迭代值,使用for k, v in d.items(),使用isinstance('abc', Iterable)檢查是否可以迭代。


python另一強大的功能在於列表生成式:[x-x*x for x in range(1,19)],而其內部可以進行多層的循環。這些語法叫做語法糖,語法糖是很方便開發者的,但是也因爲語法糖的存在其效率會有損失。



Python支持函數式編程。仔細查了查函數式編程的資料。

支持函數式編程的Lisp , python , java8,Scala , Haskell和Clojure 等。函數式編程用在數學計算和並行編程中,原有一個是函數式編程的思想來源於數學適合直截描繪出數學問題,第二個函數式編程中對象的狀態禁止修改immutable,這不會出現多線程編程中的爲了保護狀態而引入的鎖、信號量、wait/sleep/notify模式等複雜的概念,不會有線程安全的問題。java8對函數式編程的引入極大增加了java的表達能力,例如Lambda表達式。

OOP中把對象傳來傳去,函數式編程中把函數傳來傳去。有些彆扭,總是感覺少些什麼。

在函數式編程中,函數是基本單位,是第一型,他幾乎被用作一切,包括最簡單的計算,甚至連變量都被計算所取代。在函數式編程中,變量只是一個名稱,而不是一個存儲單元,這是函數式編程與傳統的命令式編程最典型的不同之處。函數式編程起源於數學。面向對象中,對象是一切,類是抽象的代言,抽象的優勢在於簡單性和重用性。在函數式編程中函數是抽象的代表,函數式編程的抽象本質則是將函數也作爲一個抽象單位,而反映成代碼形式,則是高階函數。高階函數可以接受一個或多個函數作爲參數或者返回一個函數。OOP中對象的屬性即對象的特點,是現實對象的屬性,而函數式編程是無狀態的,所以狀態保存在函數的參數中進行傳遞。

遞歸對於函數式編程卻是不可或缺的。循環是在描述我們該如何地去解決問題,遞歸是在描述這個問題的定義。遞歸分成“樹形遞歸”和“尾遞歸”,什麼是樹形遞歸,就是把計算過程逐一展開,最後形成的是一棵樹狀的結構。尾遞歸就是不要保持當前遞歸函數的狀態,而把需要保持的東西全部用參數給傳到下一個函數裏,這樣就可以自動清空本次調用的棧空間。尾遞歸解決了函數中不能定義變量並且不能賦值操作的問題。

函數式編程沒有了副作用。純邏輯的嵌套運行。函數式編程式聲明式的,對於申明式的編程範式,你不在需要提供明確的指令操作,所有的細節指令將會更好的被程序庫所封裝,你要做的只是提出你要的要求,申明你的用意即可。即不用寫明怎麼做而是說明做什麼。

命令式語言的程序員:
  要計算a和b的gcd,先檢查a和b是否相等,如果相等就打印他們之中一個並且結束;否則就把較大的那個換成他們的差,並重復這以工作。
函數式語言的程序員:
  當a和b相等時,它們的gcd就定義爲a;當a和b不相等時去計算c和d的gcd,其中c是兩個數較小的一個,d是兩個數的差。要計算給定一對數的gcd,請展開並簡化上述定義直到它結束

簡單例子:

function(x,bar){
   return bar(x);      
}

function(times,func){
   if(times<=0) return func();
   return function(){
      if(--times<1){return func.apply(this,arguments)};
   }  
}


函數式編程一大好處是代碼簡介,容易理解,接近人的語言方式。但是缺點會造成由於函數作爲參數導致的函數套函數,最後成了一個特大函數,而FP的無狀態導致I/O保持最低狀態即最少I/O時間,但是函數嵌套執行的時間多了,效率高低衆說紛紜啊。

FP易於形成封裝控制結構的內置模板函數 ,例如Python中的filter過濾器函數。FP含有了惰性求值的特點,僅僅在迭代至某個元素時才計算該元素,而在這之前或之後,元素可以不存在或者被銷燬。

柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回接受餘下的參數且返回結果的新函數的技術。

FP使用OO的思維考慮根本行不通啊。需要從how to do 改變爲what to do。what to do提出來後總得有地方或有人實現具體的細節,也就是說總是需要有how to do的部分來支持。把衆多的how to do 提取出來變成了what to do。

學習一種函數式編程語言最顯而易見的好處是,你能學會這種類型語言中的函數式概念。它能幫助你的大腦,讓它具有能非常清晰的思考和處理一些驚人的重大概念的能力。這並不是函數式編程具有魔法;各種語言和範式的出現都是爲了應對某一特定類別的問題。函數式編程的殺手鐗正是應對了當今世界上日益增長的並行性編程和元數據編程趨勢。FP是一種緊湊的編程風格,是一種編程範式,一種構建計算機結構和元素的風格,它將計算看作是對數學函數的求值,並避免改變狀態以及可變數據。可組合性是FP程序的基本能力之一。

FP中的高階函數概念類似於OOP中的模板方法。

閉包是由函數及其相關的引用環境組合而成的實體(即:閉包=函數+引用環境)。閉包把函數和運行時的引用環境打包成爲一個新的整體,所以就解決了函數編程中的嵌套所引發的問題。閉包典型例子:

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

外部函數在內部創建了新的函數,而內部函數sum可以引用外部函數lazy_sum中的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中。調用lazy_sum()時s=lazy_sum(1,2,3)返回的是函數而非結果,只有在調用s()時纔會真正執行。內部的返回函數不要引用任何循環變量,或者後續會發生變化的變量。


python支持Lambda表達式即匿名函數,以此簡化代碼。形式lambda x : ....,x是函數參數,冒號之後是對參數的操作,用於簡單的函數操作簡化。java8也對lambda表達式進行了支持加入特性之中。
每個函數都有自己的地址,有自己的名字使用function.__name__得到。
通過裝飾器可以增強函數的功能。decorator模式。decorator是一個接受一個函數並返回函數的高階函數,藉助Python的@語法,把decorator置於被修飾函數的定義上一行。原函數正常執行調用,不過執行的真正是調用decorator函數並把被修飾函數作爲參數傳進去。其實在decorator內部會有內置函數decorator返回的也是該函數,該函數內部有執行被修飾函數的語句func(......)才行。
python中的函數是按照調用和返回順序執行的。python中的很多語法是幫助創建函數的,而之所以幫助是爲了提取共有部分從而簡化編寫。

偏函數Python支持:functools.partial的作用就是,把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數,調用這個新函數會更簡單。int2 =functools.partial(int, base=2)就把int()函數的base參數固定爲2,而不需要自己再創建新的int2函數體。


python中一個.py文件稱作一個模塊module,包括python內置模塊、自己寫的模塊和第三方模塊。提高了代碼的可維護性,還可以避免函數名和變量名衝突。而組織模塊的方法使用包package,避免模塊名衝突。而package也可以有層次。模塊可以進行引用import。
模塊實例:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-   編碼格式
' a test module '    第一個字符串默認是模塊的文檔註釋
__author__ = 'Michael Liao'
import sys    導入sys模塊,擁有sys變量指向該模塊,使用sys變量可以獲得該模塊所有的函數
def test():
    args = sys.argv
    if len(args)==1:
            print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')
函數和變量是有自己的作用域的,正常的都是公開的。類似__xxx__這樣的變量是特殊變量,可以被直接引用,但是有特殊用途。類似_xxx和__xxx這樣的函數或變量就是非公開的(private),不應該被直接引用。外部不需要引用的函數全部定義成private,只有外部需要引用的函數才定義爲public。
第三方模塊安裝只需要使用命令pip install module_name即可。安裝之後就可以導入並使用了。
默認情況下,Python解釋器會搜索當前目錄、所有已安裝的內置模塊和第三方模塊,搜索路徑存放在sys模塊的path變量中。可以append自己添加。


參考文章:

http://www.defmacro.org/ramblings/fp.html

遞歸思想講解:http://www.ibm.com/developerworks/cn/java/j-lo-funinscala1/

https://mitpress.mit.edu/sicp/

http://www.cnblogs.com/huxi/archive/2011/06/18/2084316.html

FP常用的技巧:http://www.cnblogs.com/lurongkai/p/functional-programming-skills.html

閉包:http://www.cnblogs.com/Jifangliang/archive/2008/08/05/1260602.html


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