Python基礎篇

jsonchao發表於2018-07-27

簡介

成為一名優秀的Android開發,需要一份完備的知識體系,在這裡,讓我們一起成長為自己所想的那樣~。

隨著人工智慧和AI行業的興起,Python已經成為程式設計師不得不學的一門程式語言了,本篇,為Python基礎知識篇。

初識Python

what:python是什麼?
    它是一門跨平臺的高階程式語言,相對其它高階語言(如:C、Java)
    來說,它封裝的功能更完善,能用更少的程式碼實現同樣的功能。
    python的作用?
    Python的用處很多,它主要使用的領域有:
    1.前後端開發
    2.工具指令碼開發
    3.爬蟲
    4.人工智慧、AI
    優點:簡潔、易懂、用更少的程式碼實現功能模組。
    缺點:
    1.程式執行速度很慢,因為python是解釋性語言,計算機每執行一行
    python程式碼就會把它翻譯成自身能識別的機器碼,而其它語言,如
    C語言,則會在執行前就會被編譯成計算機能識別的機器碼。
    2.python不能夠加密,釋出就是將原始碼釋出出去,這正是解釋性語言
    的缺陷,而編譯型語言則不會,如C語言,它是將編譯後得到的二進位制
    碼釋出出去。
why:為什麼要使用python?
    因為它的優點——簡潔、易懂、能用更少的程式碼實現功能模組,特別適合做一些指令碼工具。
how:如何使用它?
    請往下看。。。
複製程式碼

安裝Python開發工具(Windows系統)

python有兩個版本(2.x,3.x),只演示新版本的安裝。
開啟python網站,選擇安裝Install->windows->最新relese 64bit即可,可選框全選即可。

官網安裝的python環境用的是CPython直譯器(包含python程式碼的文件稱
為.py,直譯器就是用來執行python程式碼的)。直譯器有很多種,CPython是主流。
複製程式碼

先用起來?

啟動方式?
1.開啟命令列模式,輸入python進入python互動模式。輸入exit()回到命令列模式。
2.直接點選python終端,進入python互動模式。輸入exit()退出命令列模式。

注意:python互動模式的程式碼是輸入一行,輸出一行,它只適合初學者用來
除錯程式碼時使用,正常開發都是編寫*.py檔案,使用python *.py執行*.py檔案,
這樣就會一次性執行python原始碼。(檔名只能是英文字母、數字、下劃線的組合)。
複製程式碼
輸入和輸出
輸出:使用print(),可以“”,‘’的形式輸出單個字串,也可輸出多個字串如print("hello","I","am","jsonchao"),輸出時,號相當於一個空格。

輸入:使用input(),括號內可以寫入輸入的提示資訊,如:
name = print("please enter your name:")
print("hello", name)
其中name為字串變數。
複製程式碼

python基礎

python、C、JAVA都是高階語言,它們不同於自然語言,它們需要通過直譯器
或編譯期將符合自身語法規則的語言轉換為計算機能夠執行的機器碼。

約定俗成的規則:
1.#後面為註釋;
2.語句後面加:號結尾時,縮排的語句變為程式碼塊;縮排一般為4個空格=tab鍵;
3.不同於java,複製貼上時,縮排的格式可能複製不過來,需要重起縮排格式;
4.python程式是大小寫敏感的。
複製程式碼
資料型別和變數
1.r""表示字串裡面的內容預設不轉義。
2.'''hello
    I am
    jsonchao'''為避免加入多個\n的寫法。
3.布林值:True、False首字母為大寫,and、or、not為運算子。
4.None為python中一個特殊的空值。
5.變數a = 10
    a = "10",說明python是一門變數可以動態賦值為不同型別的語言,
    稱為動態語言,而java的變數,則一開始則指定了型別,如:
    int a = 10;所以java是一門靜態語言。
6.用大寫字母規範地表示常量,雖然它的值還是可以動態改變。。。
7.除法:/,//(地板除,值取整)得到的都是浮點數結果,%(取餘,結果為整數)。
8.python的整數沒有大小限制,浮點數沒有大小限制,但是超過一定值會表示為inf(無限大)。
複製程式碼
字元編碼和字串
字元編碼:
最初的ASCLL編碼為1個位元組表示一個字元,由於不同國家有不同的編碼,為
瞭解決文字顯示不同語言亂碼的問題,國際統一了Unicode編碼,一般為2個
位元組表示一個字元(生僻的中文為4個位元組表示一個字元),為了節省
Unicode在儲存資料和傳輸資料時字元佔用過多位元組的問題,後面在儲存和
傳輸時會將Unicode轉換為UTF-8編碼,文字顯示時又會轉變回Unicode編碼。
最常用的編碼為utf-8。

Python的字串:
在最新的Python3中,字元是Unicode編碼的,因此,它能適配多語言。
1.ord()獲取字元的整數表示,chr()獲取整數對應的字元。
2.如果需要將字串在進行網路傳輸或者儲存到磁碟,就必須將其轉換成bytes(位元組)。
3.b''或b""表示裡面的為位元組,使用encode()將字串編碼為位元組,
decode()將位元組編碼為字串,括號內為指定的編譯碼格式,\x後面指定
為不能被ASCLL識別的字元。b'23\x3d3j'.decode('utf-8',errors='ignore'),以此格式指定忽略錯誤。
4.len()表示計算出字串的長度。
5.使用%d、%s、%f、%x來格式化字串,形式為:
"emm..., is %s." % (jsonchao)
"emm...,$%d,is %s." % (10000000, jsonchao)
還可以使用%0d表示0x,%.2f表示3.14這樣的形式。
用%%表示%字串。
還有另一種格式化字串的方式,使用.format(),如:
'haha,i'm {0} year\’s old, {1:.1f}%percent power'.format(24, 30.555)
注意,30.5會四捨五入為30.6。
6.'haha'.replace('h', 'd')替換指定字元。
複製程式碼
List和Tuple
List:
MyList = [10,'haha',[20, 'lala']],可儲存不同型別資料,元素還可以是List。
MyList[-1], MyList[-2]表示取出倒數第一,二個值。
MyList.append(20),結尾新增值。
MyList.insert(1, ‘haha’),下標為1處新增值。
MyList.pop(),彈出最後一個值。
MyList.pop(0),彈出第一個值。
MyList[2][1],二維取值。
MyList.sort()從小到大進行排序。

Tuple:
是不可變的,定義為:
MyTuple = (20, 'haha')
當Tuple中只表示一個元素時,必須使用MyTuple = (20,)來消除來Python以為是括號()+值的歧義。
記住不變,是指Tuple的每一個元素的指向不變,並不是指向的元素內容不變。
(相當於Java中指向元素的地址,C語言的指標)

為什麼需要元組?

1.舊式字串格式化中引數要用元組;
2.在字典中當作鍵值;
3.資料庫的返回值……

區別:即為可變與不可變。
複製程式碼
條件判斷
if:後面會執行接下來縮排的兩行程式碼。
1.elif為else if的縮寫。
2.if還有如下寫法:
if 20:
    print('nice')
只要if後的內容是非0,非空List,一切非空內容即為Ture。
elif 20 <= bmi < 25不同於java,java為bmi >= 20 &&bmi < 25。
**為java平方符合^。
複製程式碼
迴圈
names = ['tianshen', 'jsonchao', 'zhanshen']
for x in names:
    print("Hello, " + x + "!")
while
break
continue
break和continue儘量少用,易造成程式邏輯混亂。
複製程式碼
dict和set
dict稱為字典,編寫形式如下:
d = {'hello' : 1, 'haha' : 2, 'emem' : 3}
判斷是否有對應的key:
'hello' in d,有則True,無則False。
d.get('hello')獲取key對應的值。
沒有則返回none,python互動命令環境下不顯示結果。
d.pop(key)刪除指定key和對應的值。
dict和List的區別:
dict的查詢和插入速度極快,不會隨著元素的增多而變慢。
dict佔用的記憶體較多。
空間換時間。
記住,dict中的key必須是不可變元素。
key + Hash演算法計算出值的記憶體地址。  

s = set([1,2,3,3,4])
s
{1,2,3,4}
set:建立一個set,需要傳入一個List進入。
add(key)
remove(key)
set相當於一個無序和不重複元素的集合。可以使用&和|來進行交併集計算。

注意:建立空集合的時候只能用set來建立,因為在Python中{}建立的是一個空的字典:

s = {}
type(s)
dict

區別:唯一區別是set沒有儲存對應的value

整數的記憶體地址是不可變的    
對一些簡單的數值,為了提高效率,python會重用物件記憶體:
x = 2
y = 2
x is y
True

python的一些資料值被視為False的有:
False
0
None
空字串、空列表、空集合、空字典
複製程式碼

不可變集合

對應於元組(tuple)與列表(list)的關係,對於集合(set),Python提供了一種叫做不可變集合(frozen set)的資料結構。

使用 frozenset 來進行建立:


s = frozenset([1, 2, 3, 'a', 1])
s
frozenset({1, 2, 3, 'a'})

與集合不同的是,不可變集合一旦建立就不可以改變。
不可變集合的一個主要應用是用來作為字典的鍵。
複製程式碼

函式

Python中的函式類似於數學中的函式。
複製程式碼
呼叫函式

Python中內建的函式

例如:

計算類函式:abs(x),max(...)。

資料型別轉換函式:int(),str(), bool(), float()。

函式名複製給變數,該變數指向了該函式的地址。因而,具有函式的功能。
a = abs
a(-10)
輸出10。
複製程式碼
定義函式
def myAbs(x):
    if x >= 0:
        return x
    else: 
        return -x
以def為字首 + 函式名 + (引數...), return返回函式返回值,沒有return則返回None, return = return None。

空函式:使用pass構造空函式
def test:
    pass
也可以:
if a > 0:
    pass
複製程式碼
引數型別檢查
使用isinstance檢測引數型別:
def myAbs(x):
    if not isinstance (x, (int, float)):
        raise TypeError("bad opread error")
    if x >= 0:
        return x
    else:
        return -x
複製程式碼
返回多個值
當一個函式返回值有多個時,返回的是一個tuple,如(20, 30)。
複製程式碼
函式的引數
位置引數:

test(x)、test(x, y)x、y的引數定義即為位置引數。

預設引數:

def test(x , age = 3, city = 'shenzhen'),其中age和city為預設引數。
1.傳入test(0)即為傳入test(0, 3, 'shenzhen')。
2.傳入test(0, 25)即為傳入test(0, 25, 'shenzhen')。
3.傳入test(0, city = 'guangzhou')即為傳入'guangzhou',注意,當引數位置不對應時,需要指明引數型別,即city。
4.預設引數必須指向不變物件,使用test(city = none)替代test(city = []),
寫入
if(city = none):
    city = []
即可。

額外的:為什麼要設計str、none這樣的不可變物件?
可以避免在多執行緒中物件改變而造成的的錯誤,因此,儘量用不可變物件替代可變物件。

可變引數:

def test(*nums)
1.可變引數在函式呼叫時自動組裝成一個Tuple。
2.nums可以是0個或多個資料。
3.nums可以是一個List或者Tuple,此時*nums表示將List或者Tuple中的元素轉化成可變引數傳遞進去。(內容拷貝)


關鍵字引數:

def test(**nums)
1.關鍵字引數在函式呼叫時自動組裝成一個dict。
2.nums可以是0個或多個資料。
3.nums可以是一個dict,此時**nums表示將dict中的元素轉化為關鍵字引數傳遞進去。(內容拷貝)

命名關鍵字引數:

def test(a, *, b, c),*,後面的為命名關鍵字引數。
1.當函式中存在可變引數*x時,*x的作用等效於*,即此時,b、c也為命名關鍵字引數。
2.呼叫含有關鍵字引數的函式時,應該使用key = value的形式,如本例:
test(a, b = 1, c = 'haha')。
3.當函式中指定了預設值時,如def test(a, *x, b = 1, c),此時,使用函式時可不填b引數。

引數組合:

5種引數的組合順序為:
位置引數、預設引數、可變引數、命名關鍵字引數、關鍵字引數。
任意引數組合的函式都能給函式傳入function(*x, **y)的組合傳值形式。
注意:引數組合過多會影響語義,儘量避免使用多引數組合。
使用*args和**kw是習慣寫法,建議遵循。
複製程式碼
遞迴函式
1.優點:邏輯簡單清晰,缺點:呼叫過深會導致棧溢位。
2.可使用尾遞迴(返回自身本身)優化的方式避免棧溢位。
3.大多數程式語言(包括Python)的編譯器或直譯器都沒有針對尾遞迴進行優化。
複製程式碼

高階特性

程式碼越少,效率越高。
複製程式碼
切片
nums = list(range(100))
切片:nums[0:2] == nums[:2]表示取下標為0到2(不包括2)的資料。
倒數切片:nums[-2:0] == nums[-2:]表示取下標為-2到0(不包括0)的資料。
nums[:10:2]前10個數,每2個取一個。
nums[::5]所有數,每5個取一個。
nums[::-1]取倒數。
nums[:]輸出該list。
注意:nums指向的資料型別是什麼,nums[...]取出來的資料型別就是什麼。
複製程式碼
迭代器
for i in nums
不管是否有下標,只要能迭代,就能使用迭代器。
對於dict,迭代的是key,
迭代value:for i in nums.values()
迭代key、value for i in nums.items()
1.通過collections的Iterable來判讀是否能迭代:
from collections import Iterable
isinstance('abcd', Iterable)
2.使用內建的enumerate將list變成索引-元素對:
for i, j in enumerate(['a', 'b', 'c']):
    print(i, j)
複製程式碼
列表生成式
[i * i for i in range(1, 10)]
[i * i for i in range(1, 10) if i % 2 == 0]
[i * j for i in range(1, 10) for j in range(1, 10)]
[i * j for i in range(1, 10) if i % 2 == 0 for j in range(1, 10) if j % 2 == 0]
注意:'a' + 1,不同於java,python計算會出錯。

此外,列表生成式還可以生成集合和字典:
{i ** 2 for i in range(1, 10)}
{i : i ** 2 for i in range(1, 10)}

可以使用sum()得到生成式的和:
total = sum([i ** 2 for i in range(1, 10)])
但是這樣python為它生成了一個列表,並且由於沒有變數指向它,它會被放在垃圾回收器中,因此,此時使用產生式列表替代它:
total = sum(i ** 2 for i in range(1, 10))
複製程式碼
生成器
g = (x * x for x in range(10))
for i in g
一邊迴圈,一邊計算的機制稱為生成器。
獲取返回值,必須捕獲StopIterable異常。返回值就在包含在StopIterable的value中。
except StopIterable as e:
    print(e.value)
    break
普通函式和generate函式的區別
普通函式呼叫直接返回結果,generate函式呼叫返回generate物件。

def fib(max):
n, a, b = 0, 0, 1
while n < max:
    yield b
    a, b = b, a + b
    n = n + 1
return 'done'

函式中使用yield關鍵字,每次呼叫next()時,遇到yield語句就返回,再次執行next()時,又繼續從上次的位置往下執行。
複製程式碼
迭代器物件
直接作用於for迴圈的資料型別有以下幾種:
1.集合型別:list、tuple、dict、set、str等等。
2.generate型別:generate物件和generate函式。
這些可直接作用於for迴圈的物件稱為Iterable物件。

1.可直接作用於next()函式的資料型別稱為Iterator物件。
所有的生成器都是Iterator,而list、dict、str則不是。
why:Iterator至少需滿足2個條件:
    1.長度不能夠被提前知道。
    2.可以表示無限大的資料。

2.可通過iter()函式來獲得一個Iterator物件。
3.python的for迴圈的本質就是不斷呼叫next()函式來實現的。
複製程式碼

函數語言程式設計語言

抽象程度很高的程式設計正規化。只要輸入確定,輸出就確定,就是純函數語言程式設計語言。否則,則不是(當有變數存在函式中)。
特點:允許將函式作為引數傳入另一個函式,也可以返回一個函式。
複製程式碼

高階函式

變數可以指向函式
x = abs
x(-10)
10
說明變數指向函式
複製程式碼
函式名指向變數
abs是函式名,同時它也是一個變數,它指向一個計算絕對值的函式。
複製程式碼
傳入函式
既然變數可以作為引數傳入到函式中,那麼因為函式名指向變數得緣故,所以函式中可以傳入函式,傳入函式作為變數的函式稱為高階函式。
複製程式碼
map/reduce
def f(x):
    return x * x
y = map(f, [1, 3, 5])
list(y)
[1, 9, 25]
map函式傳入2個引數,第一個引數是函式,第二個是Iterable物件,map將傳入的結果依次作用到Iterable物件的每一個元素,最後返回一個Iterator(map)物件。
此外,map函式還可以作用於多個引數:
def f(x, y):
    return x * y
y = map(f, [2, 3], (2, 4))

from functools import reduce
def f(x, y):
    return x + y
reduce(f, [1, 2, 3, 4]) == f(f(f(1, 2), 3), 4)
reduce函式傳入2個引數,第一個引數是函式,第二個是Iterable物件,reduce將每次取2個元素使用函式計算,得出的結果繼續和下個元素傳入函式做計算,依次類推。
複製程式碼
filter
def is_odd(x):
    return x % 2 == 1
list(filter(is_odd, [1, 2, 3, 4]))
[1, 3]
過濾序列,同map/reduce一樣,傳入2個引數,第一個引數是函式,第二個是Iterable物件,對Iterable物件的每一個元素作用函式,返回True則保留,否則不保留。
複製程式碼
sorted
sorted(['Hello', 'JsonChao', 'quchao'], key = str.lower, reverse = True)
對字串排序是按首字母的ASCLL碼對應的值大小來進行。
key給要排序的元素作用同一個函式,reverse = True為反轉排序結果。
用sorted排序的關鍵在於實現一個對映函式。
複製程式碼

返回函式

函式作為返回值
def sum(*nums):
    def add():
        ax = 0
        for n in nums:
            ax = ax + i
        return ax
    return add
其中,add是返回函式,輸出add為函式本身,add()為函式返回值。
注意:x1 = sum(1, 3, 5)
    x2 = sum(1, 3, 5)
    x1 == x2
    輸出False。
複製程式碼

閉包

注意:返回閉包時應牢記不要引用迴圈變數和後面會發生改變的變數。
如要使用,在內部再建立一個函式,用該函式的引數繫結迴圈變數的值。
複製程式碼

匿名內部類

使用lambda實現匿名內部類,形如:
: 前面的為引數,lambda x, y : x * y
無參則為lambda: x * x
複製程式碼

模組和包

__name__屬性
當我們想讓當前.py檔案既可以當成一個模組,又可以當成作為一個指令碼使用
時,可以寫成如下:test()是該指令碼中的方法。只有.py被當做指令碼執行時
,__name__的值才會是__main__。

if __name__ == ‘__main__’:
    test()
複製程式碼
匯入模組或模組中的變數
import os 
匯入模組
from ex2 import PI
匯入ex2模組中的變數PI
from ex2 import *
匯入所有變數
複製程式碼
__init__檔案存在資料夾中則表明這是一個包。
複製程式碼

異常

try:
    ...
catch ValueError as exc:
    exc.message
    
捕捉單個異常

try:
    ...
catch (ValueError, ZeroDivisionError):
    ...
    
try:
    ...
catch ValueError:
    ...
catch ZeroDivisionError:
    ...
    
捕捉多個異常

try:
    ...
catch Expection:
    ...
    
捕捉所有異常

raise ValueError("Value error")

使用raise來丟擲異常

try:
    ... ##有異常的程式碼塊
finally:
    ...
    
finally會在try後執行,丟擲異常前執行。

try:
    ...
catch Expection:
    ...
finally:
    ...

如果異常被捕獲了,finally則會最後執行。
複製程式碼

警告

使用 warnings.warn(msg, RuntimeWarning)丟擲警告,在呼叫丟擲警告的方法前加上
warnings.filterwarnings(action = 'ignore', category = RuntimeWarning)
可過濾指定的警告。
複製程式碼

檔案讀寫

%%writefile test.txt
...

寫入檔案

f = open("test.txt")
f = file("test.txt")

開啟檔案

f.read()

讀入資料夾中的所有內容。

f.readLines()

行讀入檔案,返回一個列表,格式為:
[..../n..../n...]

f.close()

檔案讀寫完畢,關閉檔案。

f = open('test.txt', 'w')
f.write('hello, python, I come in~')
f.close()
print open('test.txt').read()

使用open函式的寫入模式來寫檔案,如果檔案不存在,則建立該檔案寫入,
如果之前已經存在該檔案,則會把之前寫入的內容覆蓋。將'w'改為'a',
即使用追加模式加入新的內容到檔案中。將'w'改為'w+'即可使用讀寫
模式,使用f.read()即可讀出檔案內容。

注意:二進位制檔案的寫入,讀取格式為'wb','rb'。
複製程式碼

很感謝您閱讀這篇文章,希望您能將它分享給您的朋友或技術群,這對我意義重大。

希望我們能成為朋友,在 Github掘金上一起分享知識。

相關文章