一、基礎(chǔ)
1.數(shù)據(jù)類型和變量
#if else語句
name = 'qqqq'
if name=='qqq':
print('true')
print('還是在if里面')
elif:**********
else:
print('false')
#轉(zhuǎn)義字符
print('dfdf\ndsfsd')
#取消轉(zhuǎn)義
print(r'\n\tsdfsfsd')
#多行內(nèi)容
print('''line1
line2
line3''')
2.list和tuple
#list展示
mylist = ['num1','num2','num3','num4']
length = len(mylist)
#list長度
print(length)
#取值
print(mylist[1])
#取最后一個
print(mylist[-1])#負(fù)數(shù)代表從后往前第幾個數(shù)據(jù)
#追加數(shù)據(jù)到list中
mylist.append('num5')
#insert到list中
mylist.insert(1,"num6")
print(mylist)
#刪除最后一個
mylist.pop()
#刪除指定位置
mylist.pop(1)
###################################
#tuple 類似list慰枕,但是建立之后不能修改
mytuple = ('t1','t2','t3')
#定義一個元素的tuple時诉濒,在后面加上分號醇份,以免歧義
mytuple1 = (1,)
#tuple是不可變的松蒜,但是在里面如果有l(wèi)ist岳遥,知識說明list的頭指針不變丢氢,但是里面的內(nèi)容是可以變的傅联。
3.循環(huán)語句
#for 循環(huán)
sum=0
mylist = [1,2,3,4,5]
for i in mylist:
sum=sum+i
print(sum)
sum1 = 0
#range(n)是指0到n-1之間的整數(shù)
for j in range(101):
sum1+=j
print(sum1)
#while循環(huán)
while sum1 > 100:
sum1-=100
4.dict和set
#dict(即key-value對)
d={'num1':1,'num2':2,'num3':3}
print(d['num2'])
#也可以賦值
d['num2']=100
#取數(shù)據(jù)
#直接取d['num2']
#使用get取
result = d.get('num2',-1)#好處是娶不到可以用默認(rèn)值等曼,不會報錯
#也可以先判斷在不在里面
if 'num2' in d:
result = d['num2']
else:
result = -1
#pop刪掉
d.pop('num2')
#set
s=set([1,2,3])
s.remove(1)#刪掉元素1忆绰,而不是第幾個元素,因?yàn)閟et內(nèi)部元素沒有次序
#set的交際并集采用&和|
5.函數(shù)
常用簡單內(nèi)置函數(shù):
abs
,max
,hex
,int()
轉(zhuǎn)換成int捻艳,float()
轉(zhuǎn)換成float
新建myfunction.py文件貌嫡,
def my_abs(x):
if not isinstance(x, (int, float)):#判斷類型比驻,只有整形和浮點(diǎn)型才行
raise TypeError('bad operand type')
if(x>=0):
return x
else:
return -x
內(nèi)容就是求絕對值,
然后再在調(diào)用的py里面岛抄,
from myfunction import my_abs
i=my_abs(-5)
print(i)
使用from指明函數(shù)來自哪里别惦,使用import知名要導(dǎo)入哪個函數(shù)。
返回多個值可以直接逗號分開夫椭,其實(shí)就是返回的tuple
python會記得默認(rèn)參數(shù)的值掸掸,因此默認(rèn)參數(shù)一定要只想不變對象!可以使用None代替
def add_end(L=None):
如果不確定入?yún)?shù)量蹭秋,可以用list或者tuple傳入扰付,但是需要組裝一個list,優(yōu)點(diǎn)麻煩仁讨。python有可變?nèi)雲(yún)⒂疠海趨?shù)名前面加上*號就行了,在里面把這個入?yún)?dāng)做list使用洞豁。
python支持關(guān)鍵字傳參禽翼。比如
def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw)
這個方法屠橄,我可以這樣調(diào)用
person('Adam', 45, gender='M', job='Engineer')
,得到的結(jié)果是:
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
很厲害是不是闰挡!特別是在一些上傳數(shù)據(jù)的情況,不一定每一個都上傳礁哄,只需要把需要的整合一下上傳就好长酗。有點(diǎn)類似于builder模式。
6.切片(字符串截韧┤蕖)
mylist = ['num1','num2','num3','num4']
print(mylist[1:3])
使用[:]方式來進(jìn)行夺脾,[1:2:3]每隔3個取一個數(shù)
7.列表生成器
[x * x for x in range(1, 11)]
就生成了[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
還能跟上條件語句
[x * x for x in range(1, 11) if x % 2 == 0]
[s.lower() for s in L]
#全部轉(zhuǎn)小寫
二.函數(shù)式編程
1.高階函數(shù)
函數(shù)名可以賦值給某一個變量,如下:
a=abs
print(a(-10))
將abs函數(shù)賦值給a茉继,照樣能夠用a()來代表原來的abs()
高階函數(shù)就是能夠?qū)⒑瘮?shù)作為參數(shù)傳遞咧叭,比如下面
def add(x, y, f):
return f(x) + f(y)
2.map/reduce編程
map就是對每一個元素進(jìn)行操作,比如我想計算list中每一個元素的平方烁竭,可以這樣寫
def f(x):
return x*x
r=map(f,[1,2,3,4,5])
print(list(r))
reduce和map相反菲茬,reduce是對整體的list進(jìn)行操作,比如想對整個list求和:
from functools import reduce
def fn(x,y):
return x+y
i = reduce(fn,[1,2,3,4,5])
print(i)
map樹輸入整體派撕,一個一個計算婉弹,輸出一個整體。reduce是輸入整體终吼,函數(shù)是一個一個計算镀赌,最后輸出一個數(shù)。reduce需要引入functools文件中的reduce庫
面向?qū)ο蟮木幊?/h2>
1.定義類际跪,然后都按照類來操作
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))
bart = Student("bart",100)
lisa = Student('Lisa',60)
bart.print_score()
lisa.print_score()
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))
bart = Student("bart",100)
lisa = Student('Lisa',60)
bart.print_score()
lisa.print_score()
如上商佛,使用init來進(jìn)行構(gòu)造,構(gòu)造的第一個參數(shù)放入self姆打,相當(dāng)于this良姆,其余的function都需要放入self。但是調(diào)用的時候不需要傳入self穴肘。
訪問權(quán)限
如果不想變量被外部訪問歇盼,在前面加上兩個_就行,比如上面的就變成:
self.__name = name
self.__score = score
這樣就需要先通過類名在訪問變量名评抚,即_Student__name這樣訪問豹缀。不建議這么做,因?yàn)閜ython可能會把內(nèi)部的變量名改掉慨代。
通過getset方式進(jìn)行數(shù)據(jù)賦值控制邢笙。
繼承
class Dog(Animal):
其實(shí)這就讓Dog繼承了Animal
python是一種動態(tài)語言,當(dāng)需要一個A類型是侍匙,不一定傳入A氮惯,可以傳入一個和A中函數(shù)名一樣的類叮雳。而靜態(tài)語言(如java)中就不行。
動態(tài)語言創(chuàng)建一個類妇汗,可以為這個對象添加額外的屬性帘不。
對象類型
使用type可以判斷屬于哪一種類型,
type(123)==int
是True
對于class的繼承關(guān)系杨箭,使用isinstance(),子類的對象屬于父類的實(shí)例寞焙,而父類創(chuàng)建的對象就不屬于子類的instanse。
為實(shí)例添加屬性和方法
from types import MethodType
class Student(object):
pass
#為實(shí)例添加屬性name
s=Student()
s.name = 'hond'
print(s.name)
#為實(shí)例添加方法設(shè)置name
def setname(self,name):
self.name = name
Student.setname = setname
s.setname('jack')
print(s.name)
設(shè)置屬性的時候直接設(shè)置就行互婿,設(shè)置方法的時候捣郊,先定義方法,定義的時候要把對象使用sel傳遞進(jìn)去慈参。然后再使用MethodType將方法賦值給對象呛牲,之后就能調(diào)用了。
使用slots來限制綁定的屬性驮配,比如:
class Students(object):
__slots__=('name','age')
就只允許添加name和age的屬性娘扩。slots屬性只對自己有效,對子類是沒有效果的
屬性的讀寫
可以使用@property來控制讀僧凤,使用@屬性名.setter來控制屬性的寫
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
上面代碼中畜侦,birth可以直接讀取,也可以直接寫入
錯誤處理代碼
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
三. IO文件操作
讀取文件
f = open('/Users/michael/test.txt', 'r')
for line in f.readlines():
print(line.strip()) # 把末尾的'\n'刪掉
內(nèi)存讀寫
(1)使用StringIO操作string數(shù)據(jù)躯保,有兩種方式
from io import StringIO
f=StringIO()
f.write('dddddddd')
f.getValue()
還有一種
from io import StringIO
f=StringIO('Hello!\nHi!\nGoodbye')
while True:
s = f.readline()
if s=='':
break
print(s)
讀寫多行的數(shù)據(jù)
(2)使用BytesIO操作二進(jìn)制數(shù)據(jù)
from io import BytesIO
f = BytesIO()
f.write(b'\xe4\xb8')
序列化
(1)固化到文件的序列化
python中的序列化叫pickling
import pickle
#將一個dict寫進(jìn)文件旋膳,二進(jìn)制
f=open('1.txt','wb')
d=dict(name='hond',age=20,score=80)
pickle.dump(d,f)
f.close()
#從文件讀取
g=open('1.txt','rb')
d=pickle.load(f)
g.close()
print(d)
(2)json序列化
import json
d=dict(name='hond',age=20,score=88)
print(json.dumps(d))
對于類的json,可以先將類轉(zhuǎn)換成dict途事,再序列化
四.進(jìn)程和線程
1.創(chuàng)建簡單進(jìn)程
from multiprocessing import Process
import os
# 子進(jìn)程要執(zhí)行的代碼
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
使用multiprocessing創(chuàng)建Process類验懊,初始化時分配給這個進(jìn)程任務(wù)。然后使用start和join進(jìn)行控制
2.創(chuàng)建多個子進(jìn)程
使用Pool進(jìn)程池
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
使用Pool分配進(jìn)程池的個數(shù)尸变,然后運(yùn)行义图,使用join等待所有子進(jìn)程結(jié)束。
進(jìn)程間通信時通過pip管道和Queue數(shù)據(jù)隊(duì)列進(jìn)行的召烂。
3.多線程
使用threading.Thread分配新的Thread碱工,并且指定這個Thread干的事情和名字
import time, threading
# 新線程執(zhí)行的代碼:
def loop():
print('thread %s is running...' % threading.current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
使用threading.Lick()來獲取鎖,然后再lock.acquire()和lock.release()釋放鎖
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要獲取鎖:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要釋放鎖:
lock.release()
使用ThreadLocal來管理每一個線程自己的獨(dú)立數(shù)據(jù)奏夫。
五.常用內(nèi)建模塊
1.datetime
datetime是處理日期和時間的標(biāo)準(zhǔn)庫怕篷,
基本用法如下:
from datetime import datetime
#獲取當(dāng)前時間
now = datetime.now()
print(now)
#設(shè)置指定日期和時間
dt = datetime(2017,3,29,12,20)
print(dt)
#將時間轉(zhuǎn)換成timestamp
ts1 = now.timestamp()
print(ts1)
ts2 = dt.timestamp()
print(ts2)
#從timestamp轉(zhuǎn)換到時間
dt2 = datetime.fromtimestamp(ts2)
print(dt2)
#到utc標(biāo)準(zhǔn)時間
dt3 = datetime.utcfromtimestamp(ts2)
print(dt3)
2.一些集合(collections模塊)
deque
雙向鏈表
defaultdict
key不存在是返回‘N/A’
orderedDict
表示key有序的map,相當(dāng)于linkehashmap酗昼。按照插入的key的順序排列廊谓。
3.使用hashlib模塊進(jìn)行摘要運(yùn)算,比如MD5,sha1等等
4.使用with語句進(jìn)行資源的調(diào)用
這一點(diǎn)和C#很類似麻削,使用with調(diào)用資源蒸痹,在with塊結(jié)束的時候系統(tǒng)會自動釋放這個資源春弥。比如:
with open('/path/to/file', 'r') as f:
f.read()
一般的類也可以采用with,但是畢竟需要釋放資源叠荠,因此需要寫好AOP的兩個函數(shù)匿沛,一個是with開始的wnter函數(shù),表示with開始蝙叛,一個是exit函數(shù)俺祠,表示with結(jié)束,清理一些資源
既然說到了AOP借帘,其實(shí)這一段也可以使用pythod的AOP @contextmanager
來進(jìn)行,
@contextmanager
def create_query(name):
print('Begin')
q = Query(name)
yield q
print('End')
開始時begin淌铐,結(jié)束時采用yield進(jìn)行結(jié)束肺然。
如果一個對象沒有上下文,可以使用closing
進(jìn)行資源關(guān)閉腿准,一樣可以用在with中
5.urllib進(jìn)行數(shù)據(jù)獲取
下面代碼獲取一個api的數(shù)據(jù)
from urllib import request
with request.urlopen('https://api.douban.com/v2/book/2129650') as f:
data = f.read()
print('Status:', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:', data.decode('utf-8'))
目前已經(jīng)出了urllib2际起,可以代替原先的urllib,使用urllib2.urlopen
和urllib2.Request
進(jìn)行數(shù)據(jù)請求
六.IO
1.協(xié)程
協(xié)程是更加輕量級的線程吐葱,但是不需要耗費(fèi)線程之間的切換代價街望,因此,使用協(xié)程有時候是最好的方案
下面的代碼是喲個生產(chǎn)者和消費(fèi)者模型
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[CONSUMER] Consuming %s...' % n)
r = '200 OK'
def produce(c):
c.send(None)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
produce使用send提供生產(chǎn)的數(shù)據(jù)弟跑,并且有返回值灾前,consumer接收到數(shù)據(jù)后,使用yield接收到r這個返回參數(shù)孟辑,并且將這個返回參數(shù)填上返回數(shù)據(jù)哎甲,producer之后就能夠接收到consumer返回的數(shù)據(jù)了。
2.asyncio
這個庫在python3.4才引入進(jìn)來
原理就是直接使用asyncio獲取一個EventLoop的引用饲嗽,將需要執(zhí)行的協(xié)程直接扔到這個EventLoop中去就行炭玫。
如下
import asyncio
@asyncio.coroutine
def hello():
print("Hello world!")
# 異步調(diào)用asyncio.sleep(1):
r = yield from asyncio.sleep(1)
print("Hello again!")
# 獲取EventLoop:
loop = asyncio.get_event_loop()
# 執(zhí)行coroutine
loop.run_until_complete(hello())
loop.close()
上面代碼中,使用@asyncio.coroutine
這個注解告訴編譯器貌虾,這個里面有異步io吞加,使用yield開始進(jìn)行協(xié)程運(yùn)算。
3.async/await
python3.5中引入
async def hello():
print("Hello world!")
r = await asyncio.sleep(1)
print("Hello again!")
使用上和其他語言的async/await沒什么區(qū)別