python學習筆記

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.sub

path = re.sub(‘[_]’, ‘/’, url1)
將_全部替換爲/

|是或的意思,匹配到兩個的任何一個都行

sd=re.compile(‘

預編譯

正則表達式每次使用都要編譯
所以先預編譯一下

兩個字符串 或匹配

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)

tuple

  1. 對於不可變類型,不管是深拷貝還是淺拷貝,都只是創建一個引用
  2. 元組爲不可變類型
  3. 對於str類型,如果兩個str相同,那麼是is和=的,這是python的優化方法,善意的謊言。。。
  4. 在小的整數上也會採取這種措施 停留interning
  5. 5.

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]] += 1

22.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 _ 將對象用字符串表示出來,如果沒實現,輸出類似於

下劃線

單下劃線,私有變量 不能通過導入來調用

雙下劃線,受保護變量 子類也不能調用

前後下劃線: 系統定義的名字

函數式編程

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)

  1. pickle 寫文件時必須指定文件名

I/O操作

按行讀取

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. 3.

python語言內部

內存管理

  1. 引用計數

將一個對象放入列表中,引用增加

分配一個新的名稱,引用增加

引用計數減少: 顯式的銷燬

sys.getrefcount( )函數可以獲得對象的當前引用計數

  1. 垃圾回收

    當引用計數清零時,垃圾回收機制

  2. == 和is 的區別

    ==比較對象的數據,is比較對象的標識(id)

  3. copy和deepcopy

    copy了後,內部對象的引用還沒有變,僅僅是複製了表面

    deepcopy是遞歸複製,完全是兩個不同的對象

  4. numpy就是一個很好地例子,它的運行速度真的非常快,因爲很多算術運算其實並不是通過Python實現的。

  5. 答:“猴子補丁”就是指,在函數或對象已經定義之後,再去改變它們的行爲。

  6. 偶爾也會出現引用循環(reference cycle)。垃圾回收器會定時尋找這個循環,並將其回收。舉個例子,假設有兩個對象o1和o2,而且符合o1.x == o2和o2.x == o1這兩個條件。如果o1和o2沒有其他代碼引用,那麼它們就不應該繼續存在。但它們的引用計數都是1。

  7. 答:print的輸出是標準輸出,可以指向任何可以輸出的流,包括http輸出

  8. 閉包: 外部函數的返回值必須是內嵌函數,可以通過外部函數的返回值來繼續調用內嵌函數,推遲函數的

鴨子類型:

走起路來像鴨子,只關心行爲

又比如list.extend()方法中,我們並不關心它的參數是不是list,只要它是可迭代的,所以它的參數可以是list/tuple/dict/字符串/生成器等.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章