python===### 地址1. mac 下python 2.7的地址 /Library/Python/2.7/3.6/Library/Frameworks/Python.framework/Versions/3.6/- 避免循環導入依賴的方法 依賴放在最后面------# 正則表達式+表示至少一個字符{n}表示n個字符 *表示任意個字符?表示0個或一個字符.可以匹配任何字符\w匹配字母\d匹配數字\s匹配一個空格r代表正則表達式^表示行的開頭,$表示行的結束\d$必須以數字結束\w$必須以字母結束多加一個\代表轉義字符'ABC\\-001'匹配:abc\001\d{3} 可以匹配:010, 230,123\s+ 表示至少一個空格\s{4}表示至少4個空格\d{3,8} 表示3到8個數字\d{3}\s+\d{3,8}\d{3} 三個數字,\s匹配一個空格 \d{3-8}3-8個數字## 進階 [0-9a-zA-Z\_] 匹配一個數字,一個字母,或者下劃線[0-9a-zA-Z\_]+ 匹配至少由一個數字字母或者下劃線組成的字符串[a-zA-Z\_][0-9a-zA-Z\_]匹配由字母或者下劃線開頭,后接任意個由一個數字,字母,下劃線組成的字符串### 方法- match 表示是否匹配,如果匹配 返回match對象,否則返回None- split() 方法用于切割 'ab c'.split(' ')- ###### finditer : 返回string中所有與pattern相匹配的全部字串,返回形式為迭代器。 ### 提取子字符串sd=re.match(r'^(\d{3})-(\d{6})','021-2345678')### 輸出第幾組函數print(sd.group(1))輸出第一組函數### 替換字符串re.subpath = re.sub('[_]', '/', url1)將_全部替換為/### |是或的意思,匹配到兩個的任何一個都行sd=re.compile('| {7}')## 預編譯正則表達式每次使用都要編譯所以先預編譯一下### 兩個字符串 或匹配sd=re.compile('/places/default/(index|view)/.*?[\d]$')#### 正則Demo```find_id = re.compile('\w{0,5}-\w{0,5}-\w{0,7}-\d{0,3}')str='fan-jia-liang-57'```## numpy函數: 1.shape函數:計算數組大小 2.mat函數 將目標數據轉換為矩陣 3.zero 函數 將數組初始化為0 4.numpy.array將list轉換為numpy的數組 5.random ranint 取隨機數 6.去掉字符串最后的換行符:line=line[:-1] 7.numpy比較兩個array是否全部相同, if(arry1==array2).all() print(true)### python讀取文件的三種方法:- f = open("foo.txt") # 返回一個文件對象 line = f. adline() # 調用文件的 readline()方法 while line: print line, # 后面跟 ',' 將忽略換行符 #####print(line, end = '') # 在 Python 3中使用 line = f.readline() f.close()- for line in open("foo.txt"): print line,- f = open("c:\\1.txt","r") lines = f.readlines()#讀取全部內容 for line in lines print line python 往txt寫內容: with open('a.txt','w') as f: for i in a: f.write(i) ### python 字符亂碼問題 ### 字符串編碼encoding 將str轉換為機器碼decoding 將機器碼轉換為str#### plt 亂碼- 在/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages下- 在py中加 plt.rcParams['font.sans-serif']=['SimHei']將simhei字體下載放在pyplot中即可解決亂碼#### requests亂碼# list- list.index()求元素的下標- str list和 int list 互相轉換 nums=[int (i) for i in nums]- s = re.findall("\d+",nums)找出字符串中所有數字- list1 = ["這", "是", "一個", "測試"] for index, content in enumerate(list1): print (index) print (content)- 元組轉List tuple =list(tuple)- list 去除重復元素 list=set(list)- 查找元素 a.index(s) 查找s元素的下標位置- 逆序輸出list reversed(a)- list的復制 ``` import copy a=[123,234,677] b=a[:] print(b) c=copy.deepcopy(a) print(c) ```### tuple1. 對于不可變類型,不管是深拷貝還是淺拷貝,都只是創建一個引用2. 元組為不可變類型3. 對于str類型,如果兩個str相同,那么是is和=的,這是python的優化方法,善意的謊言。。。4. 在小的整數上也會采取這種措施 停留interning5. ### dict#### 散列方法獲得dict[key]的值,首先調用hash(key)來計算key的散列值,把這個值的低幾位數字作為偏移量,在散列表中查找表元,如果表元是空的,就拋出異常。 如果不為空,則檢查key是否等于found_key如果相等則返回結果。如果不相等,發生散列沖突,發生的原因:在尋找元素值時,如果發生了沖突,算法會在散列值中另外取幾位。然后將新得到的數字當做索引來尋找表元。 如果找到的為空,拋出keyerror,如果沖突,重復剛才步驟#### 帶來的后果##### dict 的key值必須是可散列的, 也就是說是固定不變的,str,bytes 還有數字類型##### 消耗的空間比較大##### 鍵值的查詢很快鍵值的次序取決于添加順序對于不存在的dict 會拋出keyerror,解決方法:重寫missing方法- 字典sd, 設置元素sd[i]=i,得到元素 sd.getvalue(i)- 儲存 like_dict['a']=we- 得到dict類型的key和value print(dict.keys()) print(dict.values())- 遍歷字典 for (k,v) in dict.items() 1. #### list 和tuple 的相同點和不同點 - list和tuple 可以相互轉換,list可變,tuple不可變 - tuple比list更快更安全 - tuple是可以hash的,list不行 2. dict的內部實現,算法的實現 tuple 和list作為dict 的key值有什么問題: 3. python的多進程,協程實現和多線程 GIL全局鎖 #### 查看dict 是否有某個key值 dict.get(key)- 字典的復制 dict.copy()- python字符串反轉 str[::-1]- extends 函數a=[1,2,3,4]b=[1,2,3,4,5]a.extend(b for i in b not in a)a=[1,2,3,4,1,2,3,4,5]### 字典20.判斷一個屬性是否在字典中 print d.has_key('site') if 'sa' in dic.keys(): 應該用后面的,python3不能用前面的了?21: if value[i].get(each[i]) == None: value[i][each[i]] = 1 else: value[i][each[i]] += 122.import sys sys.version import django django.VERSION 查看各種安裝包的版本23.啟動ipython python3 -m IPython notebook-----------# python 的魔法函數## list__set__item(): __get__item():__ len __ 求元素的長度__delete_item()通過類似于list的用法,實現修改和插入。 通過對方法的重寫,方便## function__repr ___ 將對象用字符串表示出來,如果沒實現,輸出類似于__str __是在調用 str()函數時,或者print 時才會使用
__doc__在方法中''' ''' 寫的注釋? 可以得到
__call__ 調用函數的對象時默認執行的方法,可以重寫
### 下劃線
單下劃線,私有變量? 不能通過導入來調用
雙下劃線,受保護變量 子類也不能調用
前后下劃線: 系統定義的名字
## 函數式編程
map(func,rang(2)) 將func函數的返回值寫入list,然后將list返回
print reduce(lambda x, y: x * y, range(1, 5)) 將1,2傳入然后計算出結果,x=2,y=3,然后將結果給x,再找一個數給
---------------
### pickle
1.pickle存中文字符
? ? pickle.dump(json.dumps(data,ensure_ascii=False),output)
2. pickle 寫文件時必須指定文件名
# I/O操作
####? 按行讀取
```import csv
with open('A.csv','rb') as csvfile:
reader = csv.reader(csvfile)
rows = [row for row in reader] print rows
```
#### 一次讀取為str
with open('html.txt','r') as opener:
html=opener.read()
#### 按行讀取,忽略首行元素
headers=next(reader)
## 追加寫入csv文件
with open("filename.csv","a+") as csvfile:
rU 或 Ua 以讀方式打開, 同時提供通用換行符支持 (PEP 278)
a+表示追加寫入
w? ? 以寫方式打開,
a? ? 以追加模式打開 (從 EOF 開始, 必要時創建新文件)
r+? ? 以讀寫模式打開
w+? ? 以讀寫模式打s開 (參見 w )
a+? ? 以讀寫模式打開 (參見 a )
rb? ? 以二進制讀模式打開
wb? ? 以二進制寫模式打開 (參見 w )
ab? ? 以二進制追加模式打開 (參見 a )
rb+? ? 以二進制讀寫模式打開 (參見 r+ )
wb+? ? 以二進制讀寫模式打開 (參見 w+ )
ab+? ? 以二進制讀寫模式打開 (參見 a+ )
## csv
將list寫入csv文件
writer=csv.writer(open('ip_message.csv','w'))
### 按行寫入
writer.writerow(fields)
for i in result:
? ? writer.writerow((i,result[i]))
#### 將dict 寫入csv文件
```
with open('dict.csv', 'wb') as csv_file:
? ? writer = csv.writer(csv_file)
? ? for key, value in mydict.items():
? ? ? writer.writerow([key, value])
```
#### 將tuple 寫入csv
```
def write_in_csv(tuple):
? ? with open('message.csv', 'a')as opener:
? ? ? ? writers=csv.writer(opener)
? ? ? ? writers.writerow(tuple)
```
## 文件目錄和文件讀寫
```
print(__file__)
print(os.path.abspath(__file__))
上面文件目錄
path=os.path.abspath(os.path.dirname(__file__))
image_path=os.path.join(path,'dataset')
# 將目錄下文件名轉換為List
file=os.listdir(image_path)
```
# yeild
## 回調函數
將一個函數以參數形式傳到另一個函數中
--------
# 輸出
## 輸出格式
print ('a%sb%s'%(a,b))
### format
print('好的代理:{}'.format(each))
#### 多個format
print("sd{1}{0}".format(b,a))
----------https://www.baidu.com/s?wd=14.118.254.90
將變量放在字符串中輸出
```
cc=China
url='{}/{cc}/{cc}.gif'.format(BASE_URL,cc=cc.lower())
http://flupy.org/data/flags/china/china.gif
```
## 不換行輸出
pyhton2:
## 編碼
中文無法顯示的話
i.decode(encoding='utf-8')
--------
# Exception
## raise
類似于java 中的throw? 可以根據情況自己拋出異常
if response.code==200:
? ? raise RuntimeError("wwe")
except RuntimeError as e:
? ? print(e.args)
ValueError 數據轉換異常
IndexError 數組下標異常
在異常中加的參數作為args參數
### 自定義異常類
class OutboundsError(Exception):
? ? def __init__(self,errormsg):
? ? ? ? self.errormsg=errormsg
? ? def __str__(self):
? ? ? ? print("調用了這里")
? ? ? ? return self.errormsg
當打印對象時會調用 __ str__ 方法
### except
多個異常:
(KeyError,FilenotFoundError) as e:
## 配置logging
首先new一個handler
RotatingFileHandler
然后添加到app.logger
------
# 日期和日歷
## datetime
```
a = datetime(2012, 9, 23)
```
from datetime import datetime
獲得過幾天的日期
yesterday = today - datetime.timedelta(days=1) #用今天日期減掉時間差,參數為1天,獲得昨天的日期
tomorrow = today + datetime.timedelta(days=1) #用今天日期加上時間差,參數為1天,獲得明天的日期
print(afterday.year)
print(afterday.month)
print(afterday.day)
------
# 神奇的函數
### lambda 表達式的學習
a=[1,2,3,4]
g=lambda x:x**2
for each in a:
? ? print(g(each))
pydoc3 -p:5000 在5000端口查看消息
##### 根據 字母表獲得 所有字母
a=[chr(i) for i in rang(97,123)]
ord(a)=97
#### sys.argv[1]
#### 在console導入路徑或者py文件
import sys
sys.path.append("/path/to/your/test.py")
### 迭代器
```
a=iter(a)
print(next(a))
```
next函數,返回迭代器的下一個對象
## 并發
并發是指一次處理多件事。
并行是指一次做多件事。
二者不同,但是有聯系。
一個關于結構,一個關于執行。
并發用于制定方案,用來解決可能(但未必)并行的問題。
### yield
### 協程
```
def simple_coroutine():
? ? print('corroutine is start')
? ? x=yield
? ? print('corrountine reeived',x)
mycoro=simple_coroutine()
print mycoro
next(mycoro)
#向yield發送一個值,輸出x為23
mycoro.send(23)
```
###### 先要調用next函數,作為預激協程的指令,讓協程跳轉到第一個yield表達式? 產出變量的初始值None
next函數可以包裝為裝飾器
```
def start(func):
? ? def star(*args,**kwargs):
? ? ? ? sd=func(*args,**kwargs)
? ? ? ? next(sd)
? ? ? ? return sd
? ? return star
```
個人體會:通過send語句將值傳遞給yield對象
執行下一個yield讓協程進入下一個狀態
當執行完后,協程為yield狀態
python3 查看生成器狀態:
##### from inspect import getgeneratorstate
協程來處理異常類:
如果傳入的異常無法處理,協程就會終止
協程的四個狀態:
gen_created: 等待開始執行? (只有在多線程應用中才能看到)
gen_running:解釋器正在執行
gen_suspended:在yield表達式處暫停
gen_closed 執行結束
類似于return 的關鍵字,返回的類型為生成器
不過不會直接退出函數
而是等到 循環結束,返回一個list
#### yield from
可以簡化yield語法
###? GIL
global interpreter lock 全局解釋鎖
一次只能有一個線程在運行
gIL對io密集型任務 的影響很小
Python 標準庫中的所有阻塞型 I/O 函數都會釋放 GIL,允許其他線程運
行。time.sleep() 函數也會釋放 GIL。因此,盡管有 GIL,Python 線程還是能在 I/O
密集型應用中發揮作用
當某個線程在等待I/O時,python調度程序會切換到另一個線程
ProcessPool 使用了多進程來繞開多線程
### cpu密集
ProcessPoolExecutor? 多進程的 多少個核就有多少個進程
multiprocessing? 繞開GIL
python-parallelize庫
定義一個python-parallelize 裝飾器,可以應用到任何函數上
生成器: 類似于鏈表推導,
只不過只會放入內存一次
也就是說只能輸出一次,用完就沒了
#### *args,**kwargs
*args是tuple
**kwrgs是dict
def play(*args,**kwargs):
? ? print(args)
? ? print(kwargs)
(2, 3)
{'age': 3, 'name': 2}
play(2,3,name=2,age=3)
#### filter 函數
過濾函數?
- a=range(10)
print(filter(lambda x:x>3,a))
#### random
values=[1,2,3,4]
- random.choice
random.choice(values)
從List中隨機選擇元素
- 提取出n個不同的樣本
random.sample(values,2)
- random 打亂順序
random.shuffle(values)
- 生產隨機整數
random.randint(0,10)
- 生成0-1 范圍內均勻分布的浮點數
random.random()
- 生成n位隨機二進制整數
random.getrandbits(200)
### 運算符
& 按位運算符 取交集
| 按位運算符? 取并集
^ 當二進制位不相等時,取1
~ 按位取反
<< 左移運算符? 高位丟棄,低位補0
>> 右移,低位丟棄,高位補0
### 生成器
節省內存
```
pos = (n for n in mylist if n > 0)
for each in pos:
print each
```
- 列表推導
? b=[for each in b if b>0]? //占用內存比較多
- 求list中最大的元素
? print(max(mylist))
- chr(97)-> a? 輸入數字,輸出字母
- join 函數, b.join(a)? b加入a中 每個b加入到a的每個元素中
? a="sbv"? b="-"? c=b.join(a)
? print(c)
- xrange返回的為xrange類型,本質為生成器,性能不會放入內存
### input
input 會自動判斷類型
raw_input不會
input 輸入不能有空格
raw_ input可以
還是raw_input合適點
### id
查看變量地址空間
##### isinstance和type的區別
isinstance 是廣義上的判斷,可以根據父類來判斷
----
# 面向對象
## 繼承
## 構造方法的初始化
```
class A:
? ? def spam(self):
? ? ? ? print('A.spam')
class B(A):
? ? def spam(self):
? ? ? ? print('B.spam')
? ? ? ? super().spam()? # Call parent spam()
```
----
## 抽象類
## 裝飾器
裝飾器是可調用對象,其參數是另一個函數
不改變函數的前提下,增強函數的功能
在導入時執行調用
1. @property
將方法變為屬性
本質是為了增加原的功能。
將原函數作為參數傳到另一個函數中
相當于方法套了一層方法。
def identify(f):
? ? print(f())
? ? return ()
def foo():
? ? return 'bar'
identify(foo)
上面等價于:
def identify(f):
print(f())
@identify
def foo():
return "sd"
閉包;
## 一些坑
- a//2 還是int 類型? a/=2 就是float類型
-----
## pip
- pip list --outdate
列出所有可以升級的軟件
-? pip install? --upgrade requests
升級一個包
- 升級所有可用的包
for i in `pip list -o --format legacy|awk '{print $1}'` ; do pip install --upgrade $i; done
# OS
__ file __ 屬性為當前py文件的路徑
execv(file,args)
execv()執行一個新的程序,用新的程序代替子進程的空間
### 面試問題
1. 深拷貝和淺拷貝的區別 深拷貝和淺拷貝復制一個對象,然后把之前的對象刪掉,引用技術應該怎么變
2. 對一個對象進行如何操作才能使他的引用計數增加或者減少
3. python垃圾回收機制
4. 復制一個list的方法
5. python內部list和tuple的實現的數據結構 數組
6. 數據庫索引,b樹和b+樹的實現和區別,為什么不用紅黑樹
7. ping的端口號 基于什么協議的
? 基于iCMP協議,沒有端口號? 控制報文協議
8. python? ? _ _init_ _方法和_ _? _new_ _的區別
? new: 創造對象是調用,會返回當前對象的一個實例
? init: 創造完對象后調用,無返回值
? 同時存在,會優先調用new方法
? new_是靜態方法,init是實例方法
9. python的閉包函數? 變量在閉包中調用的次序
10. 每行大小為16個字節,總共1G大小的文件,限制內存1MB,找出頻率出現次數最多的單詞
? ? 解決方法: 1mb內存可以處理 2^16次方個單詞,首先進行切分為100個文件,然后
11. 如何從一個很長的字符串來找一個子字符串 KMP算法
哪些是可變類型
哪些是不可變類型
深拷貝和淺拷貝的區別
裝飾器的特點
裝飾器有哪些優點
1. 便于開發
2. 便于代碼復用
3.
## python語言內部
#### 內存管理
1. 引用計數
將一個對象放入列表中,引用增加
分配一個新的名稱,引用增加
引用計數減少: 顯式的銷毀
sys.getrefcount( )函數可以獲得對象的當前引用計數
2. 垃圾回收
? 當引用計數清零時,垃圾回收機制
3. == 和is 的區別?
? ==比較對象的數據,is比較對象的標識(id)
4. copy和deepcopy
? copy了后,內部對象的引用還沒有變,僅僅是復制了表面
? deepcopy是遞歸復制,完全是兩個不同的對象
5. numpy就是一個很好地例子,它的運行速度真的非常快,因為很多算術運算其實并不是通過Python實現的。
6. 答:“猴子補丁”就是指,在函數或對象已經定義之后,再去改變它們的行為。
7. 偶爾也會出現引用循環(reference cycle)。垃圾回收器會定時尋找這個循環,并將其回收。舉個例子,假設有兩個對象o1和o2,而且符合o1.x == o2和o2.x == o1這兩個條件。如果o1和o2沒有其他代碼引用,那么它們就不應該繼續存在。但它們的引用計數都是1。
8. 答:print的輸出是標準輸出,可以指向任何可以輸出的流,包括http輸出
9. 閉包: 外部函數的返回值必須是內嵌函數,可以通過外部函數的返回值來繼續調用內嵌函數,推遲函數的
鴨子類型:
走起路來像鴨子,只關心行為
又比如list.extend()方法中,我們并不關心它的參數是不是list,只要它是可迭代的,所以它的參數可以是list/tuple/dict/字符串/生成器等.