廖雪峰python3 教程

觀其大綱

1 python基礎(chǔ)

2 函數(shù)

3 高級特性

4 函數(shù)式編程

5 模塊

6 面向?qū)ο缶幊?/h3>

7 面向?qū)ο蟾呒壘幊?/h3>

8 錯誤,調(diào)試和測試

9 IO編程

10 進程和線程

11 正則表達(dá)式

12 常用第三方模塊

13 virtualenv

14 圖形界面

15 網(wǎng)絡(luò)編程

16 電子郵件

17 訪問數(shù)據(jù)庫

18 web開發(fā)

19 異步I/O




大綱細(xì)節(jié)

1 python基礎(chǔ)

數(shù)據(jù)類型和變量
字符串和編碼
數(shù)據(jù)結(jié)構(gòu)
條件判斷
循環(huán)

2 函數(shù)

3 高級特性

切片
迭代
列表生成式
生成器
迭代器

4 函數(shù)式編程

高階函數(shù)
返回函數(shù)
匿名函數(shù)
裝飾器
偏函數(shù)

5 模塊

6 面向?qū)ο缶幊?/h3>

類和實例
訪問限制
繼承和多態(tài)
獲取對象信息
實例屬性和類屬性

7 面向?qū)ο蟾呒壘幊?/h3>

slots
@property
多重繼承
定制類
枚舉類
元類

8 錯誤,調(diào)試和測試

錯誤處理
調(diào)試
單元測試
文檔測試

9 IO編程

文件讀寫
String IO 和Bytes IO
操作文件和目錄
序列化

10 進程和線程

11 正則表達(dá)式

12 常用第三方模塊

13 virtualenv

14 圖形界面

15 網(wǎng)絡(luò)編程

TCP 編程
UDP 編程

16 電子郵件

SMTP發(fā)送郵件
POP3收取郵件

17 訪問數(shù)據(jù)庫

18 web開發(fā)

19 異步I/O




熟知概念

1 python基礎(chǔ)

python2與Python3輸入輸出區(qū)別
  • print

在Python2和Python3中都提供print()方法來打印信息,
1.python3中print是一個內(nèi)置函數(shù),有多個參數(shù),而python2中print是一個語法結(jié)構(gòu);
2.Python2打印時可以不加括號:print 'hello world', Python3則需要加括號 print("hello world")

  • input

1、在python2.x中raw_input( )和input( ),兩個函數(shù)都存在,其中區(qū)別為
raw_input( )---將所有輸入作為字符串看待,返回字符串類型
input( )-----只能接收“數(shù)字”的輸入,在對待純數(shù)字輸入時具有自己的特性,它返回所輸入的數(shù)字的類型( int, float )
2、在python3.x中raw_input( )和input( )進行了整合,去除了raw_input( ),僅保留了input( )函數(shù),其接收任意任性輸入,將所有輸入默認(rèn)為字符串處理,并返回字符串類型。

Python 3 print 函數(shù)用法總結(jié)

print("runoob")  # 輸出字符串
print(100)            # 輸出數(shù)字
print(str)            # 輸出變量
print(L)        # 可直接打印列表,元組,字典
---------------------------
支持參數(shù)格式化,與 C 語言的 printf 類似
>>>str = "the length of (%s) is %d" %('runoob',len('runoob'))
>>> print(str)
the length of (runoob) is 6
-------
print('%10.3f' % pi) #字段寬10,精度3  
---------
在 Python 中 print 默認(rèn)是換行的 print (i)
要想不換行你應(yīng)該寫成 print(i, end = '' )
數(shù)據(jù)類型和變量
數(shù)據(jù)類型

備注
字符串和編碼

Python2的 默認(rèn)編碼 是ASCII,不能識別中文字符,需要顯式指定字符編碼;Python3的 默認(rèn)編碼 為Unicode,可以識別中文字符。
一個字符不等價于一個字節(jié),字符是人類能夠識別的符號,而這些符號要保存到計算的存儲中就需要用計算機能夠識別的字節(jié)來表示。
UNICDOE才是真正的字符串,而用ASCII、UTF-8、GBK等字符編碼表示的是字節(jié)串。
編碼(encode):將Unicode字符串(中的代碼點)轉(zhuǎn)換特定字符編碼對應(yīng)的字節(jié)串的過程和規(guī)則
解碼(decode):將特定字符編碼的字節(jié)串轉(zhuǎn)換為對應(yīng)的Unicode字符串(中的代碼點)的過程和規(guī)則


image.png

創(chuàng)建一個工程之后先確認(rèn)該工程的字符編碼是否已經(jīng)設(shè)置為UTF-8
為了兼容Python2和Python3,在代碼頭部聲明字符編碼:-- coding:utf-8 --

數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)
內(nèi)置方法和函數(shù)

一 :數(shù)字類型


數(shù)字類型轉(zhuǎn)換
image.png

二:列表


image.png
image.png

image.png

三: 元組


image.png

image.png

四: 字典


image.png
image.png
條件判斷
循環(huán)

2 函數(shù)

def 函數(shù)名(參數(shù)列表):
函數(shù)體

函數(shù)參數(shù)5種類型
1必選參數(shù):
def func(x):

2默認(rèn)參數(shù):
def func(x=12):

3可變參數(shù):
def func(*num):
輸入多個數(shù)據(jù),num將作為元組保存。
num可以是list或者tuple

4關(guān)鍵字參數(shù):
def func(**kw):
輸入的kw將以字典的形式保存,如 a=1,b=2,c=3
kw也可以是字典

5命名關(guān)鍵字參數(shù):
def func(*, name ,age):
輸入key:name 和age的value
如 name=bob, age=21
變量必須與給定的參數(shù)相同類似于關(guān)鍵字變量。

3 高級特性

切片

list、tuple、string都可以使用切片功能
第一個元素的索引為0,倒數(shù)第一個元素的索引為-1

迭代

可迭代對象
集合數(shù)據(jù)類型:list、tuple dict set str
generator,包括生成器和帶yield的generator function

list、tuple的迭代可以采用for...in完成。
dict的存儲與list的順序排列不同。默認(rèn)dict迭代的是key。
如果要迭代value,可以用for value in d.values()。
如果要迭代key、value,可以用for k,v in d.items()
對list實現(xiàn)類似Java的下標(biāo)循環(huán),采用enumerate可以把一個list變成索引-元素對,可以在for同時迭代索引和元素本身
for i,value in enumerate(['A','B','C'])
print(i,value)

列表生成式

生成[1,2,3,4,5,6,7,8,9,10]可以用list(range(1,11))
[xx for x in range(1,11)]
[x
x for x in range(1,11) if x%2 == 0 ]
[m + n for m in 'ABC' for n in 'XYZ']

生成器

如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計算的機制,稱為生成器:generator。
要創(chuàng)建一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就創(chuàng)建了一個generator:

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

如果要一個一個打印出來,可以通過next()函數(shù)獲得generator的下一個返回值
next(g)

迭代器

可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator。
list、tuple、dict、set、str, generator 這些可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:Iterable。
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
把list、dict、str等Iterable變成Iterator可以使用iter()函數(shù)

4 函數(shù)式編程

高階函數(shù)

Python內(nèi)建了map()和reduce()函數(shù)。

  • map()函數(shù)接收兩個參數(shù),一個是函數(shù),一個是Iterable,map將傳入的函數(shù)依次作用到序列的每個元素,并把結(jié)果作為新的Iterator返回。
>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
  • reduce把一個函數(shù)作用在一個序列[x1, x2, x3, ...]上,這個函數(shù)必須接收兩個參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個元素做累積計算
    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
filter

Python內(nèi)建的filter()函數(shù)用于過濾序列。
和map()類似,filter()也接收一個函數(shù)和一個序列。和map()不同的是,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。

def is_odd(n):
    return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 結(jié)果: [1, 5, 9, 15]

sorted

排序算法
排序也是在程序中經(jīng)常用到的算法。無論使用冒泡排序還是快速排序,排序的核心是比較兩個元素的大小。

sorted([36, 5, -12, 9, -21])
sorted([36, 5, -12, 9, -21], key=abs)
sorted(['bob', 'about', 'Zoo', 'Credit'])
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
 sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)

返回函數(shù)

高階函數(shù)除了可以接受函數(shù)作為參數(shù)外,還可以把函數(shù)作為結(jié)果值返回。

匿名函數(shù)

當(dāng)我們在傳入函數(shù)時,有些時候,不需要顯式地定義函數(shù),直接傳入匿名函數(shù)更方便。

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> f = lambda x: x * x
>>> f(5)
25

閉包

在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包
內(nèi)部函數(shù)對外部函數(shù)作用域里變量的引用(非全局變量),則稱內(nèi)部函數(shù)為閉包。

def line_conf(a, b):
    def line(x):
        return a*x + b
    return line
# 函數(shù)line與變量a,b構(gòu)成閉包。

裝飾器

裝飾器本質(zhì)其實就是一個函數(shù), 可以讓其它函數(shù)不改動源代碼的情況下增加其他新功能

@timmer
def add(x, y):
    print(x,y)
add(1,2)
相當(dāng)于
def add(x, y):
    print(x,y)
add = timmer(add)
add(1,2)

被多個裝飾器裝飾

@a
@b
@c
def func():
    pass
相當(dāng)于
func = a(b(c(func)))

偏函數(shù)

functools.partial可以設(shè)置默認(rèn)參數(shù)和關(guān)鍵字參數(shù)的默認(rèn)值
Python的functools模塊提供了很多有用的功能,其中一個就是偏函數(shù)(Partial function)。要注意,這里的偏函數(shù)和數(shù)學(xué)意義上的偏函數(shù)不一樣。

int()函數(shù)可以把字符串轉(zhuǎn)換為整數(shù),當(dāng)僅傳入字符串時,int()函數(shù)默認(rèn)按十進制轉(zhuǎn)換
但int()函數(shù)還提供額外的base參數(shù),默認(rèn)值為10。如果傳入base參數(shù),就可以做N進制的轉(zhuǎn)換

int('12345', 16)
74565
意思是將16進制12345轉(zhuǎn)化為整數(shù)
簡單總結(jié)functools.partial的作用就是,把一個函數(shù)的某些參數(shù)給固定?。ㄒ簿褪窃O(shè)置默認(rèn)值),返回一個新的函數(shù),調(diào)用這個新函數(shù)會更簡單

int2 = functools.partial(int, base=2)
相當(dāng)于
def int2(x, base=2):
    return int(x, base)

當(dāng)函數(shù)的參數(shù)個數(shù)太多,需要簡化時,使用functools.partial可以創(chuàng)建一個新的函數(shù),這個新函數(shù)可以固定住原函數(shù)的部分參數(shù),從而在調(diào)用時更簡單。

5 模塊

一.模塊
1.一個包含所有你定義的函數(shù)和變量的文件,其后綴名是.py,即一個.py文件就是一個模塊
2.一個模塊只會被導(dǎo)入一次,不管你執(zhí)行了多少次import。這樣可以防止導(dǎo)入模塊被一遍又一遍地執(zhí)行
3.導(dǎo)入模塊 support時,需要把命令放在腳本的頂端
4.當(dāng)解釋器遇到 import 語句,如果模塊在當(dāng)前的搜索路徑就會被導(dǎo)入
5.使用模塊名稱來訪問函數(shù)
二.搜索路徑
1.模塊的查找順序是:內(nèi)存中已經(jīng)加載的模塊->內(nèi)置模塊->sys.path路徑(導(dǎo)模塊的環(huán)境變量)中包含的模塊
2.當(dāng)Python執(zhí)行import語句時,它會在一些路徑中搜索Python模塊和擴展模塊。可以通過sys.path查看這些路徑
3.當(dāng)安裝第三方模塊的時候,如果不是按照標(biāo)準(zhǔn)方式安裝,則為了能夠引用(import)這些模塊,必須將這些模塊的安裝路徑添加到sys.path中
4.只要模塊文件放在sys.path路徑中,都可以import使用它
二.導(dǎo)入模塊import
1.將整個模塊(somemodule)導(dǎo)入,格式為:import somemodule
2.從某個模塊中導(dǎo)入某個函數(shù),格式為:from somemodule import somefunction
3.從某個模塊中導(dǎo)入多個函數(shù),格式為:from somemodule import firstfunc, secondfunc, thirdfunc
4.將某個模塊中的全部函數(shù)導(dǎo)入,格式為: from somemodule import *
5.引用模塊時使用別名,格式為:import somemodule as othername
6.*表示能匹配到的資源,存放在all=[ ](列表中每個元素都是字符串)

通過包來組織模塊,避免沖突。方法是選擇一個頂層包名,比如mycompany,按照如下目錄存放
mycompany
├─ web
│ ├─ init.py
│ ├─ utils.py
│ └─ www.py
├─ init.py
├─ abc.py
└─ xyz.py
文件www.py的模塊名就是mycompany.web.www,兩個文件utils.py的模塊名分別是mycompany.utils和mycompany.web.utils。
請注意,每一個包目錄下面都會有一個init.py的文件,這個文件是必須存在的,否則,Python就把這個目錄當(dāng)成普通目錄,而不是一個包。init.py可以是空文件,也可以有Python代碼,因為init.py本身就是一個模塊,而它的模塊名就是mycompany。

Python本身就內(nèi)置了很多非常有用的模塊,只要安裝完畢,這些模塊就可以立刻使用。
我們以內(nèi)建的sys模塊為例,編寫一個hello的模塊:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'Michael Liao'
import sys
def test():
  ....
  ....

if __name__=='__main__':
    test()

注意到這兩行代碼:

if __name__=='__main__':
    test()

當(dāng)我們在命令行運行hello模塊文件時,Python解釋器把一個特殊變量name置為main,而如果在其他地方導(dǎo)入該hello模塊時,if判斷將失敗,因此,這種if測試可以讓一個模塊通過命令行運行時執(zhí)行一些額外的代碼,最常見的就是運行測試。

sys模塊
導(dǎo)入sys模塊后,我們就有了變量sys指向該模塊,利用sys這個變量,就可以訪問sys模塊的所有功能。
sys模塊有一個argv變量,用list存儲了命令行的所有參數(shù)。argv至少有一個元素,因為第一個參數(shù)永遠(yuǎn)是該.py文件的名稱,例如:
運行python3 hello.py獲得的sys.argv就是['hello.py'];
運行python3 hello.py Michael獲得的sys.argv就是['hello.py', 'Michael]。

安裝第三方分模塊
pip install module_name
我們推薦直接使用Anaconda,這是一個基于Python的數(shù)據(jù)處理和科學(xué)計算平臺,它已經(jīng)內(nèi)置了許多非常有用的第三方庫,我們裝上Anaconda,就相當(dāng)于把數(shù)十個第三方模塊自動安裝好了,非常簡單易用。

6 面向?qū)ο缶幊?/h3>

類和實例

面向?qū)ο笞钪匾母拍罹褪穷悾–lass)和實例(Instance),必須牢記類是抽象的模板,比如Student類,而實例是根據(jù)類創(chuàng)建出來的一個個具體的“對象”,每個對象都擁有相同的方法,但各自的數(shù)據(jù)可能不同。

定義類是通過class關(guān)鍵字:
class Student(object):
    pass
-------------------
根據(jù)Student類創(chuàng)建出Student的實例,創(chuàng)建實例是通過類名+()實現(xiàn)的
 bart = Student()
----------------------
可以自由地給一個實例變量綁定屬性,比如,給實例bart綁定一個name屬性:
bart.name = 'Bart Simpson'
-----------------
由于類可以起到模板的作用,因此,可以在創(chuàng)建實例的時候,
把一些我們認(rèn)為必須綁定的屬性強制填寫進去。
通過定義一個特殊的__init__方法,在創(chuàng)建實例的時候,
就把name,score等屬性綁上去:
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
__init__方法的第一個參數(shù)永遠(yuǎn)是self,表示創(chuàng)建的實例本身,
因此,在__init__方法內(nèi)部,就可以把各種屬性綁定到self,
因為self就指向創(chuàng)建的實例本身。
數(shù)據(jù)封裝
封裝的另一個好處是可以給Student類增加新的方法,比如get_grade:
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

訪問限制

如果要讓內(nèi)部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線,在Python中,實例的變量名如果以開頭,就變成了一個私有變量(private),只有內(nèi)部可以訪問,外部不能訪問,所以,我們把Student類改一改:

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

無法從外部訪問實例變量.__name和實例變量.__score

如果又要允許外部代碼修改私有變量該怎么辦?例如__score可以再給Student類增加set_score方法:

class Student(object):
    ...

    def set_score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

繼承和多態(tài)

在OOP程序設(shè)計中,當(dāng)我們定義一個class的時候,可以從某個現(xiàn)有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。
class Dog(Animal):
pass
由于Animial實現(xiàn)了run()方法,因此,Dog作為它的子類,什么事也沒干,就自動擁有了run()方法:
dog = Dog()
dog.run()
當(dāng)子類和父類都存在相同的run()方法時,我們說,子類的run()覆蓋了父類的run(),在代碼運行的時候,總是會調(diào)用子類的run()。這樣,我們就獲得了繼承的另一個好處:多態(tài)。
當(dāng)我們定義一個class的時候,我們實際上就定義了一種數(shù)據(jù)類型。我們定義的數(shù)據(jù)類型和Python自帶的數(shù)據(jù)類型,比如str、list、dict沒什么兩樣
判斷一個變量是否是某個類型可以用isinstance()判斷:

>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> isinstance(c, Dog)
True
  • 著名的“開閉”原則:
    對擴展開放:允許新增Animal子類;
    對修改封閉:不需要修改依賴Animal類型的run_twice()等函數(shù)。

獲取對象信息

  • 判斷對象類型,使用type()函數(shù):
>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>
>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>
  • 對于class的繼承關(guān)系來說,使用type()就很不方便。我們要判斷class的類型,可以使用isinstance()函數(shù)。
>>> isinstance(d, Dog) and isinstance(d, Animal)
True
## 并且還可以判斷一個變量是否是某些類型中的一種,
比如下面的代碼就可以判斷是否是list或者tuple:
>>> isinstance([1, 2, 3], (list, tuple))
True

-使用dir(): 獲得一個對象的所有屬性和方法
它返回一個包含字符串的list,比如,獲得一個str對象的所有屬性和方法:

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__',
 'capitalize', 'casefold',..., 'zfill']
##類似__xxx__的屬性和方法在Python中都是有特殊用途的
  • getattr()、setattr()以及hasattr(),我們可以直接操作一個對象的狀態(tài)
>>> hasattr(obj, 'x') # 有屬性'x'嗎?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有屬性'y'嗎?
False
>>> setattr(obj, 'y', 19) # 設(shè)置一個屬性'y'
>>> hasattr(obj, 'y') # 有屬性'y'嗎?
True
>>> getattr(obj, 'y') # 獲取屬性'y'
19
>>> obj.y # 獲取屬性'y'
19

7 面向?qū)ο蟾呒壘幊?/h3>

slots

@property

多重繼承

定制類

枚舉類

元類

8 錯誤,調(diào)試和測試

錯誤處理
調(diào)試
單元測試
文檔測試

9 IO編程

文件讀寫
String IO 和Bytes IO
操作文件和目錄
序列化

10 進程和線程

11 正則表達(dá)式

12 常用第三方模塊

13 virtualenv

14 圖形界面

15 網(wǎng)絡(luò)編程

TCP 編程
UDP 編程

16 電子郵件

SMTP發(fā)送郵件
POP3收取郵件

17 訪問數(shù)據(jù)庫

18 web開發(fā)

19 異步I/O

最后編輯于
?著作權(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)容