Python簡易教程

注明:本教程內(nèi)容源自網(wǎng)絡(luò)資源,大部分出自Vamei:http://www.cnblogs.com/vamei,小部分出自其他作者,本人只做了內(nèi)容提取與整理。


Python基礎(chǔ)

內(nèi)置函數(shù)type(),查詢變量類型

print的另一個(gè)用法,print后跟多個(gè)輸出,以逗號分隔。

序列有兩種:tuple(定值表; 也有翻譯為元組) 和 list (表)。tuple和list的主要區(qū)別在于,一旦建立,tuple的各個(gè)元素不可再變更,而list的各個(gè)元素可以再變更。序列元素的下標(biāo)從0開始,元素類型可以不同。

字符串是一種特殊的元組。

print(5 in [1,3,5]) # 5是list [1,3,5]的一個(gè)元素,打印布爾值,是否存在,這里為True

print(not True ) # not, “非”運(yùn)算, 取反

range(x)功能是新建一個(gè)表。這個(gè)表的元素都是整數(shù),從0開始,下一個(gè)元素比前一個(gè)大1, 直到函數(shù)中所寫的上限 (不包括該上限本身),還可以以步進(jìn)方式創(chuàng)建表。

Python的函數(shù)允許不返回值,也就是不用return。默認(rèn)返回的是None,函數(shù)可以返回多個(gè)值,逗號隔開,實(shí)際返回的是一個(gè)tuple元組對象

參數(shù)傳遞:對于基本數(shù)據(jù)類型的變量,變量傳遞給函數(shù)后,函數(shù)會在內(nèi)存中復(fù)制一個(gè)新的變量,從而不影響原來的變量(我們稱此為值傳遞)。但是對于復(fù)雜對象(如三種序列對象)來說,傳遞給函數(shù)的是一個(gè)指針,指針指向?qū)ο笤趦?nèi)存中的位置,在函數(shù)中對對象的操作將在原有內(nèi)存中進(jìn)行,從而影響原有變量。 (我們稱此為指針傳遞)

定義類的函數(shù)時(shí),方法的第一個(gè)參數(shù)必須是self,無論是否用到,self只限內(nèi)部使用,不用傳參。

子類繼承父類的所有屬性,包括變量屬性和方法屬性。

Python有一些特殊方法。Python會特殊的對待它們。特殊方法的特點(diǎn)是名字前后有兩個(gè)下劃線,如類的構(gòu)造方法。

python對象屬性和類屬性,訪問修改及內(nèi)存模型中的大坑需要注意,和其他語言不太一樣。

dir()用來查詢一個(gè)類或者對象所有屬性。

運(yùn)算符是特殊方法,在類內(nèi)部定義了該運(yùn)算符的方法。


Python進(jìn)階

詞典的元素沒有順序。你不能通過下標(biāo)引用元素。詞典是通過鍵來引用。

在詞典中增添一個(gè)新元素的方法:引用一個(gè)新的鍵,并賦予它對應(yīng)的值。而表list添加元素是append,而元組tuple不能增刪改元素。

刪除詞典元素用del,如del(dict['key1'])

文本文件讀寫:open(filename,mode)構(gòu)建文件對象,然后調(diào)用file對象操作文件讀寫。

在Python中,一個(gè).py文件就構(gòu)成一個(gè)模塊。通過模塊,你可以調(diào)用其它文件中的程序。

可以將功能相似的模塊放在同一個(gè)文件夾中,構(gòu)成一個(gè)模塊包。該文件夾中必須包含一個(gè)__init__.py的文件,提醒Python,該文件夾為一個(gè)模塊包。init.py可以是一個(gè)空文件。

python的函數(shù)調(diào)用參數(shù)傳遞有幾種方式:參數(shù)列表的參數(shù)位置傳遞,關(guān)鍵字傳遞(形參名=實(shí)參),也可以混用,但是根據(jù)位置傳遞的參數(shù)要正確得放在參數(shù)列表前面。

包裹:變長參數(shù),python的變長參數(shù)定義時(shí)用name的方式告訴函數(shù)這是變長參數(shù),包裹成一個(gè)tuple元組。若需要變長的鍵值對作為參數(shù),即包裹的參數(shù)是字典,需要以*name的方式通知函數(shù)。

解包裹:在調(diào)用函數(shù)的時(shí)候,需要傳入的是固定的幾個(gè)參數(shù),但是現(xiàn)在數(shù)據(jù)是一個(gè)元組或者字典,則可以直接用解包的方式將該集合元素打散分別作為對應(yīng)參數(shù)傳入函數(shù)。方式同包裹一樣,元組用,字典用*。

參數(shù)列表順序:先位置,再關(guān)鍵字,再包裹位置,再包裹關(guān)鍵字。

enumerate()函數(shù),可以在每次循環(huán)中同時(shí)得到下標(biāo)和元素。range函數(shù)只能得到元素值,不會得到index。

如果你多個(gè)等長的序列,然后想要每次循環(huán)時(shí)從各個(gè)序列分別取出一個(gè)元素,可以利用zip()方便地實(shí)現(xiàn),就是依次取矩陣的第一列、第二列……,取出的元素組成一個(gè)元組。

循環(huán)對象和for循環(huán)調(diào)用之間還有一個(gè)中間層,就是要將循環(huán)對象轉(zhuǎn)換成迭代器(iterator)。循環(huán)只能針對可循環(huán)的對象實(shí)施,他們都有next方法

生成器:generator,用于自定義循環(huán)對象。

理解生成器表達(dá)式(Generator Expression):

G = (x for x in range(4))

表推導(dǎo):list comprehension,快速生成表。與生成器類似,利用的是循環(huán)對象。

L = [x**2 for x in range(10)] # L=[0,1,4,9,16,25,36,49,64,81]
xl = [1,3,5]
yl = [9,12,13]
L  = [ x**2 for (x,y) in zip(xl,yl) if y > 10]
# L = [9,25]

函數(shù)也是一個(gè)對象,具有屬性,可用dir()查詢。

函數(shù)可以作為一個(gè)對象,進(jìn)行參數(shù)傳遞。python函數(shù)參數(shù),數(shù)值類型是值傳遞,其他都是引用傳遞。

lambda生成一個(gè)函數(shù)對象

func = lambda x,y: x + y # 這里lambda語句生成一個(gè)函數(shù)對象,引用賦值給func

map(func,collection)函數(shù),作用是將函數(shù)func依次作用于collection的每個(gè)元素,這個(gè)函數(shù)func可以是lambda語句生成的函數(shù)對象。map返回的是一個(gè)結(jié)果集的循環(huán)對象,可用list()函數(shù)將其轉(zhuǎn)為list。

re = map((lambda x,y: x+y),[1,2,3],[6,7,9]) 
# map()將每次從兩個(gè)表中分別取出一個(gè)元素,帶入lambda所定義的函數(shù)

filter(func,[10,56,101,500]),filter函數(shù)的第一個(gè)參數(shù)也是一個(gè)函數(shù)對象。它也是將作為參數(shù)的函數(shù)對象作用于多個(gè)元素。如果函數(shù)對象返回的是True,則該次的元素被儲存于返回的表中,filter返回的不是表,而是循環(huán)對象(同樣需要list函數(shù)轉(zhuǎn)換)。

def func(a):
    if a > 100:
        return True
    else:
        return False
# 返回的循環(huán)對象裝換為list為[101,500],不是Ture False之類的func的返回值
print(filter(func,[10,56,101,500]))

reduce函數(shù)的第一個(gè)參數(shù)也是函數(shù),但有一個(gè)要求,就是這個(gè)函數(shù)自身能接收兩個(gè)參數(shù)。reduce可以累進(jìn)地將函數(shù)作用于各個(gè)參數(shù)。

reduce((lambda x,y: x+y),[1,2,5,7,9]) 
# 相當(dāng)于(((1+2)+5)+7)+9
# 使用reduce需要導(dǎo)入 functools包

異常代碼塊的執(zhí)行:try->異常->except->finally,try->無異常->else->finally。也可手動拋出異常,raise 異常對象

對象存儲模型:列表可以通過引用其元素,改變對象自身(in-place change)。這種對象類型,稱為可變數(shù)據(jù)對象(mutable object),詞典也是這樣的數(shù)據(jù)類型。而像之前的數(shù)字和字符串,不能改變對象本身,只能改變引用的指向,稱為不可變數(shù)據(jù)對象(immutable object)。我們之前學(xué)的元組(tuple),盡管可以調(diào)用引用元素,但不可以賦值,因此不能改變對象自身,所以也算是immutable object.

def f(x):
    x[0] = 100
    print(x)

a = [1,2,3]
f(a)
print(a)
# 輸出[100,2,3]
# 這里a和x指向同一個(gè)對象,但是list對象是可變數(shù)據(jù)對象,通過引用元素改變了x[0]的值

Python深入

Python的運(yùn)算符是通過調(diào)用對象的特殊方法實(shí)現(xiàn)的。如+:

'abc' + 'xyz'               # 連接字符串
'abc'.__add__('xyz')        # 實(shí)際執(zhí)行這個(gè)特殊方法

許多內(nèi)置函數(shù)也都是調(diào)用對象的特殊方法,如:

len([1,2,3])      # 返回表中元素的總數(shù)
[1,2,3].__len__() # 實(shí)際調(diào)用

在Python中,函數(shù)也是一種對象。實(shí)際上,任何一個(gè)有__call__()特殊方法的對象都被當(dāng)作是函數(shù)。

對于內(nèi)置的對象來說(比如整數(shù)、表、字符串等),它們所需要的特殊方法都已經(jīng)在Python中準(zhǔn)備好了。而用戶自己定義的對象也可以通過增加特殊方法,來實(shí)現(xiàn)自定義的語法。

任何定義了__enter__()和__exit__()方法的對象都可以用于上下文管理器。使用上下文管理器以 (with...as...)代碼塊的形式

with open("new.txt", "w") as f:
    print(f.closed)
    f.write("Hello World!")
print(f.closed) # 到這里,在上面的縮進(jìn)代碼塊中f已經(jīng)調(diào)用了它的__exit__函數(shù)關(guān)閉了
# __exit__(self,exc_type,exc_value,traceback):后是三個(gè)參數(shù)用于異常處理

Python一切皆對象(object),每個(gè)對象都可能有多個(gè)屬性(attribute)。Python的屬性有一套統(tǒng)一的管理方案。

可以利用class屬性找到對象的類,然后調(diào)用類的base屬性來查詢父類

property特性使用內(nèi)置函數(shù)property()來創(chuàng)建。property()最多可以加載四個(gè)參數(shù)。前三個(gè)參數(shù)為函數(shù),分別用于處理查詢特性、修改特性、刪除特性。最后一個(gè)參數(shù)為特性的文檔,可以為一個(gè)字符串,起說明作用。

閉包

函數(shù)是一個(gè)對象,所以可以作為某個(gè)函數(shù)的返回結(jié)果。如果定義該函數(shù)時(shí),函數(shù)內(nèi)部調(diào)用了外部的變量,那么稱這個(gè)外部變量為這個(gè)函數(shù)的環(huán)境變量,在函數(shù)作為返回值返回的時(shí)候,這個(gè)依賴的環(huán)境變量也是默認(rèn)攜帶返回的。一個(gè)函數(shù)和它的環(huán)境變量合在一起,構(gòu)成一個(gè)閉包(closure)。故閉包就是一個(gè)包含環(huán)境變量的函數(shù)對象,環(huán)境變量的值存在這個(gè)函數(shù)對象的__closure__屬性中。閉包可以減少參數(shù),有利于并行計(jì)算環(huán)境下的編程。

def line_conf(a, b):
    def line(x):
        return a*x + b
    return line

line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))

裝飾器

decorator,類似于裝飾模式,或者切面編程,可以用來增強(qiáng)方法或者類。利用的實(shí)際是函數(shù)對象這個(gè)概念。定義裝飾器的時(shí)候,實(shí)際就是在裝飾器對象內(nèi)部定義一個(gè)新的函數(shù),再作為返回值返回,調(diào)用的時(shí)候,直接用@裝飾器作用于需要被裝飾的函數(shù)定義之前。

# 可以對裝飾器再加一層裝飾,并多添加幾個(gè)參數(shù),實(shí)際上是一種閉包方式
def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F

# get square sum
@decorator
def square_sum(a, b):
    return a**2 + b**2

# get square diff
@decorator
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))
# 類的裝飾,為Bird類增加屬性total_display,用以增強(qiáng)display方法,記錄其調(diào)用次數(shù)
def decorator(aClass):
    class newClass:
        def __init__(self, age):
            self.total_display   = 0
            self.wrapped         = aClass(age)
        def display(self):
            self.total_display += 1
            print("total display", self.total_display)
            self.wrapped.display()
    return newClass

@decorator
class Bird:
    def __init__(self, age):
        self.age = age
    def display(self):
        print("My age is",self.age)

eagleLord = Bird(5)
for i in range(3):
    eagleLord.display()

內(nèi)存

is用于判斷兩個(gè)引用(變量名)所指的對象是否相同(python緩存小的數(shù)字和字符,所以is判定為True)。

sys包中的getrefcount(),來查看某個(gè)對象的引用計(jì)數(shù)。但是這個(gè)函數(shù)一調(diào)用,參數(shù)本身就會增加一個(gè)對象的引用,故該函數(shù)返回值會比預(yù)期多1.

可以使用del關(guān)鍵字刪除某個(gè)引用。

手動回收垃圾:gc.collect(),需要導(dǎo)入gc模塊

引用計(jì)數(shù)的GC方式,留意“孤立環(huán)問題”


Python補(bǔ)充

使用__name__做單元測試

多種import語法

import TestLib as t
print(t.lib_func(120))

from TestLib import *
print(lib_func(120))

from TestLib import lib_func  #只引用部分對象,減小內(nèi)存開銷
print(lib_func(120))

查詢對象所屬的類和類名稱

a = [1, 2, 3]
print a.__class__
print a.__class__.__name__

使用中文#coding=utf8 ,或者 #-- coding: UTF-8 --

腳本與命令行結(jié)合

可以使用下面方法運(yùn)行一個(gè)Python腳本,在腳本運(yùn)行結(jié)束后,直接進(jìn)入Python命令行。這樣做的好處是腳本的對象不會被清空,可以通過命令行直接調(diào)用。

$python -i script.py

內(nèi)置函數(shù)

基本數(shù)據(jù)類型 type()

反過頭來看看 dir() help() len()

詞典 len()

文本文件的輸入輸出 open()

循環(huán)設(shè)計(jì) range() enumerate() zip()

循環(huán)對象 iter()

函數(shù)對象 map() filter() reduce()

在Python中,下列對象都相當(dāng)于False: [], (), {}, 0, None, 0.0, ''


Python標(biāo)準(zhǔn)庫

分類

python增強(qiáng):文字處理(正則、string)、數(shù)據(jù)對象(array、queue)、日期時(shí)間(time、datetime)、數(shù)學(xué)運(yùn)算(random、math)、存儲(pickle對象持久化、數(shù)據(jù)庫sqlite3)

系統(tǒng)互動:python運(yùn)行控制(sys包,解釋器自己)、操作系統(tǒng)(os包)、線程與進(jìn)程(threading、multiprocessing)

網(wǎng)絡(luò):socket、asyncore

正則,re

正則表達(dá)式(regular expression)主要功能是從字符串(string)中通過特定的模式(pattern),搜索想要找到的內(nèi)容。

m = re.search(pattern, string)  # 搜索整個(gè)字符串,直到發(fā)現(xiàn)符合的子字符串。
m = re.match(pattern, string)   # 從頭開始檢查字符串是否符合正則表達(dá)式。必須從字符串的第一個(gè)字符開始就相符。

# 在string中利用正則變換pattern進(jìn)行搜索,對于搜索到的字符串,用另一字符串replacement替換。返回替換后的字符串。
str = re.sub(pattern, replacement, string) 

re.split()    # 根據(jù)正則表達(dá)式分割字符串, 將分割后的所有子字符串放在一個(gè)表(list)中返回
re.findall()  # 根據(jù)正則表達(dá)式搜索字符串,將所有符合的子字符串放在一給表(list)中返回

正則的書寫:看正則文檔

^ 字符串的起始位置 $ 字符串的結(jié)尾位置

時(shí)間日期,time、datetime

import time
# 時(shí)間戳
print(time.time())   # wall clock time, unit: second
# 用以測試程序性能,cpu空閑該時(shí)間不計(jì)時(shí)
print(time.clock())  # processor clock time, unit: second

time.sleep(10) # 可以將程序置于休眠狀態(tài),定時(shí)休眠10秒

datetime可以理解為date和time兩個(gè)組成部分。date是指年月日構(gòu)成的日期(相當(dāng)于日歷),time是指時(shí)分秒微秒構(gòu)成的一天24小時(shí)中的具體時(shí)間(相當(dāng)于手表)。你可以將這兩個(gè)分開管理(datetime.date類,datetime.time類),也可以將兩者合在一起(datetime.datetime類)。

# 時(shí)間和字符串的轉(zhuǎn)換
from datetime import datetime
format = "output-%Y-%m-%d-%H%M%S.txt" 
str    = "output-1997-12-23-030000.txt" 
t      = datetime.strptime(str, format)
# 反過來,我們也可以調(diào)用datetime對象的strftime()方法,來將datetime對象轉(zhuǎn)換為特定格式的字符串

路徑與文件,os.path、glob

import os.path
path = '/home/vamei/doc/file.txt'

print(os.path.basename(path))    # 查詢路徑中包含的文件名
print(os.path.dirname(path))     # 查詢路徑中包含的目錄

info = os.path.split(path)       # 將路徑分割成文件名和目錄兩個(gè)部分,放在一個(gè)表中返回
path2 = os.path.join('/', 'home', 'vamei', 'doc', 'file1.txt')  # 使用目錄名和文件名構(gòu)成一個(gè)路徑字符串

p_list = [path, path2]
print(os.path.commonprefix(p_list))    # 查詢多個(gè)路徑的共同部分

os.path.normpath(path)   # 去除路徑path中的冗余。比如'/home/vamei/../.'被轉(zhuǎn)化為'/home'

#-----------------------------------------------------------------------

# os.path還可以查詢文件信息
import os.path 
path = '/home/vamei/doc/file.txt'

print(os.path.exists(path))    # 查詢文件是否存在

print(os.path.getsize(path))   # 查詢文件大小
print(os.path.getatime(path))  # 查詢文件上一次讀取的時(shí)間
print(os.path.getmtime(path))  # 查詢文件上一次修改的時(shí)間

print(os.path.isfile(path))    # 路徑是否指向常規(guī)文件
print(os.path.isdir(path))     # 路徑是否指向目錄文件

glob包最常用的方法只有一個(gè), glob.glob(Filename Pattern Expression),列出所有符合該表達(dá)式的文件,類似于命令 ls

文件管理,shutil

os包包括各種各樣的函數(shù),以實(shí)現(xiàn)操作系統(tǒng)的許多功能

from os import *
mkdir(path)
# 創(chuàng)建新目錄,path為一個(gè)字符串,表示新目錄的路徑。相當(dāng)于$mkdir命令

rmdir(path)
#刪除空的目錄,path為一個(gè)字符串,表示想要?jiǎng)h除的目錄的路徑。相當(dāng)于$rmdir命令

listdir(path)
#返回目錄中所有文件。相當(dāng)于$ls命令。

remove(path)
# 刪除path指向的文件。

rename(src, dst)
# 重命名文件,src和dst為兩個(gè)路徑,分別表示重命名之前和之后的路徑。 

chmod(path, mode)
# 改變path指向的文件的權(quán)限。相當(dāng)于$chmod命令。

chown(path, uid, gid)
# 改變path所指向文件的擁有者和擁有組。相當(dāng)于$chown命令。

stat(path)
# 查看path所指向文件的附加信息,相當(dāng)于$ls -l命令。

symlink(src, dst)
# 為文件dst創(chuàng)建軟鏈接,src為軟鏈接文件的路徑。相當(dāng)于$ln -s命令。

getcwd()
# 查詢當(dāng)前工作路徑 (cwd, current working directory),相當(dāng)于$pwd命令。

shutil包

copy(src, dst) # 復(fù)制文件,從src到dst。相當(dāng)于$cp命令。

move(src, dst) # 移動文件,從src到dst。相當(dāng)于$mv命令。

存儲對象,pickle

# 序列化到對象到磁盤文件
import pickle

# define class
class Bird(object):
    have_feather = True
    way_of_reproduction  = 'egg'

summer       = Bird()                 # construct an object
picklestring = pickle.dumps(summer)   # serialize object,文本流字符串

# 直接dump到文件中
fn           = 'a.pkl'
with open(fn, 'w') as f:                     # open file with write-mode
    picklestring = pickle.dump(summer, f)   # serialize and save object
    
# ---------------------------------------------------------------------
# 從文件中反序列化對象
import pickle

# define the class before unpickle,這里不像java有類的字節(jié)碼,這里需要重新一份一樣的類定義給解釋器知道該怎么反序列化,jvm可以直接通過class的字節(jié)碼知道
class Bird(object):
    have_feather = True
    way_of_reproduction  = 'egg'

fn     = 'a.pkl'
with open(fn, 'r') as f:
    summer = pickle.load(f)   # read file and build object

cPickle包的功能和用法與pickle包幾乎完全相同 (其存在差別的地方實(shí)際上很少用到),不同在于cPickle是基于c語言編寫的,速度是pickle包的1000倍。

子進(jìn)程,subprocess

subprocess包主要功能是執(zhí)行外部的命令和程序,類似與shell。通過標(biāo)準(zhǔn)庫中的subprocess包來fork一個(gè)子進(jìn)程,并運(yùn)行一個(gè)外部的程序,另外subprocess還提供了一些管理標(biāo)準(zhǔn)流(standard stream)和管道(pipe)的工具,從而在進(jìn)程間使用文本通信。

多線程

我們在函數(shù)中使用global來聲明變量為全局變量(定義函數(shù)的時(shí)候引用外部變量)

threading.Thread對象來代表線程,用threading.Lock對象來代表一個(gè)互斥鎖 (mutex)。

import threading
import time
import os

# This function could be any function to do other chores.
def doChore():
    time.sleep(0.5)

# Function for each thread
def booth(tid):
    global i
    global lock
    while True:
        lock.acquire()                # Lock; or wait if other thread is holding the lock
        if i != 0:
            i = i - 1                 # Sell tickets
            print(tid,':now left:',i) # Tickets left
            doChore()                 # Other critical operations
        else:
            print("Thread_id",tid," No more tickets")
            os._exit(0)              # Exit the whole process immediately
        lock.release()               # Unblock
        doChore()                    # Non-critical operations

# Start of the main function
i    = 100                           # Available ticket number 
lock = threading.Lock()              # Lock (i.e., mutex)

# Start 10 threads
for k in range(10):
    new_thread = threading.Thread(target=booth,args=(k,))   # Set up thread; target: the callable (function) to be run, args: the argument for the callable 
    new_thread.start()                                      # run the thread

面向?qū)ο笫蕉嗑€程

import threading
import time
import os

# This function could be any function to do other chores.
def doChore():
    time.sleep(0.5)

# Function for each thread
class BoothThread(threading.Thread):
    def __init__(self, tid, monitor):
        self.tid          = tid
        self.monitor = monitor
        threading.Thread.__init__(self)
    def run(self):
        while True:
            monitor['lock'].acquire()                          # Lock; or wait if other thread is holding the lock
            if monitor['tick'] != 0:
                monitor['tick'] = monitor['tick'] - 1          # Sell tickets
                print(self.tid,':now left:',monitor['tick'])   # Tickets left
                doChore()                                      # Other critical operations
            else:
                print("Thread_id",self.tid," No more tickets")
                os._exit(0)                                    # Exit the whole process immediately
            monitor['lock'].release()                          # Unblock
            doChore()                                          # Non-critical operations

# Start of the main function
monitor = {'tick':100, 'lock':threading.Lock()}

# Start 10 threads
for k in range(10):
    new_thread = BoothThread(k, monitor)
    new_thread.start()

定義了一個(gè)類BoothThread, 這個(gè)類繼承自thread.Threading類。然后我們把上面的booth()所進(jìn)行的操作統(tǒng)統(tǒng)放入到BoothThread類的run()方法中。注意,我們沒有使用全局變量聲明global,而是使用了一個(gè)詞典monitor存放全局變量,然后把詞典作為參數(shù)傳遞給線程函數(shù)。由于詞典是可變數(shù)據(jù)對象,所以當(dāng)它被傳遞給函數(shù)的時(shí)候,函數(shù)所使用的依然是同一個(gè)對象,相當(dāng)于被多個(gè)線程所共享。

數(shù)學(xué)與隨機(jī)

# 從序列的元素中隨機(jī)挑選一個(gè)元素,比如random.choice(range(10)),從0到9中隨機(jī)挑選一個(gè)整數(shù)。
random.choice(seq)  
random.sample(seq,k) # 從序列中隨機(jī)挑選k個(gè)元素
random.shuffle(seq)  # 將序列的所有元素隨機(jī)排序

random.random()          # 隨機(jī)生成下一個(gè)實(shí)數(shù),它在[0,1)范圍內(nèi)。
random.uniform(a,b)      # 隨機(jī)生成下一個(gè)實(shí)數(shù),它在[a,b]范圍內(nèi)。

random.gauss(mu,sigma)    # 隨機(jī)生成符合高斯分布的隨機(jī)數(shù),mu,sigma為高斯分布的兩個(gè)參數(shù)。
random.expovariate(lambd) # 隨機(jī)生成符合指數(shù)分布的隨機(jī)數(shù),lambd為指數(shù)分布的參數(shù)。

循環(huán)器

在 for i in iterator 結(jié)構(gòu)中,循環(huán)器每次返回的對象將賦予給i,直到循環(huán)結(jié)束。使用iter()內(nèi)置函數(shù),我們可以將諸如表、字典等容器變?yōu)檠h(huán)器。

標(biāo)準(zhǔn)庫中的itertools包提供了更加靈活的生成循環(huán)器的工具。

def height_class(h):
    if h > 180:
        return "tall"
    elif h < 160:
        return "short"
    else:
        return "middle"

friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]

friends = sorted(friends, key = height_class)
# 將friends按照height_class函數(shù)進(jìn)行分組,并返回分組標(biāo)號和元素循環(huán)器對象
for m, n in groupby(friends, key = height_class):
    print(m)
    print(list(n))

數(shù)據(jù)庫,sqlite3

Python自帶一個(gè)輕量級的關(guān)系型數(shù)據(jù)庫SQLite,Python標(biāo)準(zhǔn)庫中的sqlite3提供該數(shù)據(jù)庫的接口。

# 創(chuàng)建數(shù)據(jù)庫
import sqlite3

# test.db is a file in the working directory.
conn = sqlite3.connect("test.db")

c = conn.cursor()

# create tables
c.execute('''CREATE TABLE category
      (id int primary key, sort int, name text)''')
c.execute('''CREATE TABLE book
      (id int primary key, 
       sort int, 
       name text, 
       price real, 
       category int,
       FOREIGN KEY (category) REFERENCES category(id))''')

# save the changes
conn.commit()

# close the connection with the database
conn.close()
# 插入數(shù)據(jù)
import sqlite3

conn = sqlite3.connect("test.db")
c    = conn.cursor()

books = [(1, 1, 'Cook Recipe', 3.12, 1),
            (2, 3, 'Python Intro', 17.5, 2),
            (3, 2, 'OS Intro', 13.6, 2),
           ]

# execute "INSERT" 
c.execute("INSERT INTO category VALUES (1, 1, 'kitchen')")

# using the placeholder
c.execute("INSERT INTO category VALUES (?, ?, ?)", [(2, 2, 'computer')])

# execute multiple commands
c.executemany('INSERT INTO book VALUES (?, ?, ?, ?, ?)', books)

conn.commit()
conn.close()
# 查詢
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()

# retrieve one record
c.execute('SELECT name FROM category ORDER BY sort')
print(c.fetchone())
print(c.fetchone())

# retrieve all records as a list
c.execute('SELECT * FROM book WHERE book.category=1')
print(c.fetchall())

# iterate through the records
for row in c.execute('SELECT name, price FROM book ORDER BY sort'):
    print(row)
# 更新與刪除
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()

# retrieve one record
c.execute('SELECT name FROM category ORDER BY sort')
print(c.fetchone())
print(c.fetchone())

# retrieve all records as a list
c.execute('SELECT * FROM book WHERE book.category=1')
print(c.fetchall())

# iterate through the records
for row in c.execute('SELECT name, price FROM book ORDER BY sort'):
    print(row)
# 刪除數(shù)據(jù)表
c.execute('DROP TABLE book')

Python面向?qū)ο?/h2>

繼承、多繼承

Python支持多繼承,但是不同類型的類多繼承時(shí)方法的搜索不同。經(jīng)典類就是在類定義時(shí)沒有顯示繼承Object的類。推薦使用新式類,某類在定義時(shí)顯示繼承object,那么該類的繼承樹下的所有子類都是新式類。

img
img
  • 當(dāng)類是經(jīng)典類時(shí),多繼承情況下,會按照深度優(yōu)先方式查找
  • 當(dāng)類是新式類時(shí),多繼承情況下,會按照廣度優(yōu)先方式查找
img

類的成員可以分為三大類:字段、方法和屬性

img

所有成員中,只有普通字段的內(nèi)容保存對象中,即:根據(jù)此類創(chuàng)建了多少對象,在內(nèi)存中就有多少個(gè)普通字段。而其他的成員,則都是保存在類中,即:無論對象的多少,在內(nèi)存中只創(chuàng)建一份。

每種類的成員都有兩種形式:

  • 公有成員,在任何地方都能訪問
  • 私有成員,只有在類的內(nèi)部才能方法

私有成員和公有成員的定義不同:私有成員命名時(shí),前兩個(gè)字符是下劃線(特殊成員除外,例如:__init__、__call__、__dict__等)。

特殊成員:

# __doc__: 類的描述信息
# __module__ 表示當(dāng)前操作的對象在那個(gè)模塊
# __class__ 表示當(dāng)前操作的對象的類是什么
# __init__ 構(gòu)造方法,通過類創(chuàng)建對象時(shí),自動觸發(fā)執(zhí)行
# __del__ 析構(gòu)方法,當(dāng)對象在內(nèi)存中被釋放時(shí),自動觸發(fā)執(zhí)行。
# __call__ 對象后面加括號,觸發(fā)執(zhí)行。
# __dict__ 類或?qū)ο笾械乃谐蓡T(注意成員的內(nèi)存模型,對應(yīng)去尋找)
# __str__ 如果一個(gè)類中定義了__str__方法,那么在打印 對象 時(shí),默認(rèn)輸出該方法的返回值。相當(dāng)于toString
# __getitem__、__setitem__、__delitem__用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)
# __getslice__、__setslice__、__delslice__該三個(gè)方法用于分片操作
# __iter__ 用于迭代器,讓該類對象可以直接用于循環(huán)迭代

字段

字段包括:普通字段和靜態(tài)字段,他們在定義和使用中有所區(qū)別,而最本質(zhì)的區(qū)別是內(nèi)存中保存的位置不同,

  • 普通字段屬于對象
  • 靜態(tài)字段屬于
class Province:

    # 靜態(tài)字段
    country = '中國'

    def __init__(self, name):

        # 普通字段
        self.name = name


# 直接訪問普通字段
obj = Province('河北省')
print obj.name

# 直接訪問靜態(tài)字段
Province.country
img

方法

方法包括:普通方法、靜態(tài)方法和類方法,三種方法在內(nèi)存中都?xì)w屬于類,區(qū)別在于調(diào)用方式不同。

  • 普通方法:由對象調(diào)用;至少一個(gè)self參數(shù);執(zhí)行普通方法時(shí),自動將調(diào)用該方法的對象賦值給self;
  • 類方法:由調(diào)用; 至少一個(gè)cls參數(shù);執(zhí)行類方法時(shí),自動將調(diào)用該方法的復(fù)制給cls
  • 靜態(tài)方法:由調(diào)用;無默認(rèn)參數(shù);
class Foo:

    def __init__(self, name):
        self.name = name

    def ord_func(self):
        """ 定義普通方法,至少有一個(gè)self參數(shù) """

        # print self.name
        print '普通方法'

    @classmethod
    def class_func(cls):
        """ 定義類方法,至少有一個(gè)cls參數(shù) """

        print '類方法'

    @staticmethod
    def static_func():
        """ 定義靜態(tài)方法 ,無默認(rèn)參數(shù)"""

        print '靜態(tài)方法'


# 調(diào)用普通方法
f = Foo()
f.ord_func()

# 調(diào)用類方法
Foo.class_func()

# 調(diào)用靜態(tài)方法
Foo.static_func()
img

屬性

Python中的屬性其實(shí)是普通方法的變種。

屬性的定義有兩種方式:

  • 裝飾器 即:在方法上應(yīng)用裝飾器
  • 靜態(tài)字段 即:在類中定義值為property對象的靜態(tài)字段

一、裝飾器方式

# 經(jīng)典類,具有一種@property裝飾器
class Goods:

    @property
    def price(self):
        return "wupeiqi"
# ############### 調(diào)用 ###############
obj = Goods()
result = obj.price  # 自動執(zhí)行 @property 修飾的 price 方法,并獲取方法的返回值
# 新式類,具有三種@property裝飾器
class Goods(object):

    @property # 屬性定義,同時(shí)相當(dāng)于get方法
    def price(self):
        print '@property'

    @price.setter # 相當(dāng)于set方法
    def price(self, value):
        print '@price.setter'

    @price.deleter # 屬性的delete方法
    def price(self):
        print '@price.deleter'

# ############### 調(diào)用 ###############
obj = Goods()

obj.price          # 自動執(zhí)行 @property 修飾的 price 方法,并獲取方法的返回值

obj.price = 123    # 自動執(zhí)行 @price.setter 修飾的 price 方法,并將  123 賦值給方法的參數(shù)

del obj.price      # 自動執(zhí)行 @price.deleter 修飾的 price 方法

二、靜態(tài)字段方式,創(chuàng)建值為property對象的靜態(tài)字段

class Foo:

    def get_bar(self):
        return 'wupeiqi'

    BAR = property(get_bar)

obj = Foo()
reuslt = obj.BAR        # 自動調(diào)用get_bar方法,并獲取方法的返回值
print reuslt
'''
    property的構(gòu)造方法中有個(gè)四個(gè)參數(shù):
    第一個(gè)參數(shù)是方法名,調(diào)用 對象.屬性 時(shí)自動觸發(fā)執(zhí)行方法
    第二個(gè)參數(shù)是方法名,調(diào)用 對象.屬性 = XXX 時(shí)自動觸發(fā)執(zhí)行方法
    第三個(gè)參數(shù)是方法名,調(diào)用 del 對象.屬性 時(shí)自動觸發(fā)執(zhí)行方法
    第四個(gè)參數(shù)是字符串,調(diào)用 對象.屬性.__doc__ ,此參數(shù)是該屬性的描述信息

'''
class Foo:

    def get_bar(self):
        return 'wupeiqi'

    # *必須兩個(gè)參數(shù)
    def set_bar(self, value): 
        return return 'set value' + value

    def del_bar(self):
        return 'wupeiqi'

    BAR = property(get_bar, set_bar, del_bar, 'description...')

obj = Foo()

obj.BAR              # 自動調(diào)用第一個(gè)參數(shù)中定義的方法:get_bar
obj.BAR = "alex"     # 自動調(diào)用第二個(gè)參數(shù)中定義的方法:set_bar方法,并將“alex”當(dāng)作參數(shù)傳入
del Foo.BAR          # 自動調(diào)用第三個(gè)參數(shù)中定義的方法:del_bar方法
obj.BAE.__doc__      # 自動獲取第四個(gè)參數(shù)中設(shè)置的值:description...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容