天天看點

python重新學習(持續更新)

1. 字元編碼:

ASCII碼:1個字元以一位元組儲存
Unicode碼:字元通常2位元組存儲,非常偏僻的字4個位元組,**示例如下 **
           
A    
中       
           
utf-8碼:英文字元1位元組,漢字通常3位元組,偏僻字4-6位元組
           
用記事本編輯時,從檔案讀取的utf-8字元被替換為Unicode字元到記憶體中,編輯完成時,儲存的時候Unicode被轉換為utf-8儲存到檔案

python的字元串:ord(),chr():字母與ASCII碼數字互換

  • Unicode碼的表示:u‘…’
  • 把u’…’ 轉換為utf-8編碼’…’ 用encode(‘utf-8’),反過來用decode(‘utf-8’)
  • 儲存源代碼時,若源碼包括中文,加上 #*_coding:utf-8_*
  • 格式化顯示:

    類似于C:

2.資料類型

dict:字典,查找速度快,不會因字典變大而變慢。實作這種特性的算法是雜湊演算法(hash)
    set: 不重複,可通過remove()删元素
    list:清單,通過pop()删元素
           
#python中,不可變對象永遠不可變,如字元串
a='ABC'
b=a.replace('A','t')       #b=''tBC'   a='ABC'    
           
python資料類型轉換:int() ,float() ,str() ,unicode() ,bool()

3.函數

函數名其實就是指向一個函數對象的引用,完全可以把函數賦給一個變量

空函數:

def nop():
    pass
           

pass還可以用于其他語句:

if age >=:
    pass
           

python函數:預設參數在後,必選參數在前;預設參數必須指向不變對象(str,None)

args—–可變參數:以表示,表示傳入參數個數可變,組裝成tuple

kw——關鍵字參數:以表示,在函數調用時直接組裝成dict

>>> kw = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', , **kw)
name: Jack age:  other: {'city': 'Beijing', 'job': 'Engineer'}
           

遞歸函數:每調用一次,棧加一層棧幀,函數傳回,棧減一層棧幀,易溢出

def fn(n):
    if n==:
        return 
    return n*fn(n-)    
           

尾遞歸:函數傳回時,調用自身,并且return語句不包含表達式

def fact(n):
    return fact_iter(n,)
def fact_iter(num,product):
    if num==:return product
    return fact_iter(num-,num*product)
           

但python編譯器沒有對尾遞歸做優化,故依然會棧溢出

3.進階特性

python疊代

形式:for key in d:

若d為dict,預設疊代key

for k,v in d.iteritems():
           

python 内置的enumerate可以把list變成索引-元素對

for i,value in enumerate(['A','B','C']):
           

清單生成式:

[x*x for xin range(,)]
[k+'='+v for k,v in d.iteritems()]
           

使用isinstance 可判斷一個變量是否為字元串

生成器generator:

g=(x*x for x in range())
           

generator 儲存的是算法,可以節省空間。

對于函數,若定義中包含yield關鍵字,那麼該函數為生成器

>>> def odd():
...     print 'step 1'
...     yield 
...     print 'step 2'
...     yield 
...     print 'step 3'
...     yield 
...
>>> o = odd()
>>> o.next()
step 

>>> o.next()
step 

>>> o.next()
step 

>>> o.next()
Traceback (most recent call last):
  File "<stdin>", line , in <module>
StopIteration
           

4.高階函數

map:将傳入的函數依次作用到序列每個元素

reduce:

reduce(f,[1,b,c])  #f(f(a,b),c)
           

filter:把傳入的函數依次作用于每個元素,實作篩選元素

def not_empty(s):
    return s and s.strip()

filter(not_empty, ['A', '', 'B', None, 'C', '  '])
# 結果: ['A', 'B', 'C']
           

sorted函數:用于排序,預設從小到大

from operator import itemgetter
b=sorted(a,key=itemgetter())  #對value排序
b=sorted(a,reverse=)  #倒序
           

裝飾器:decorator

def log(func):
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper

@log
def now():
    print '2013-12-25'
           

如果decorator本身需要傳入參數,那就需要編寫一個傳回decorator的高階函數,寫出來會更複雜。比如,要自定義log的文本:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print '%s %s():' % (text, func.__name__)
            return func(*args, **kw)
        return wrapper
    return decorator
@log('execute')
def now():
    print '2013-12-25'      
>>> now = log('execute')(now) 
           

由于裝飾後的now()函數的name屬性已經變成了 wrapper,是以,需要把原始函數的name等屬性複制到wrapper()函數中,這時候可以利用到Python内置的functools.wraps

import functools

def log(func):
    @functools.wraps(func)   #在wrapper前面加上這一句
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper
           
import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print '%s %s():' % (text, func.__name__)
            return func(*args, **kw)
        return wrapper
    return decorator
           

安裝第三方子產品:pip,easy_install

子產品搜尋路徑:預設目前目錄,但可以增添。搜尋路徑存放在sys子產品的path變量中

import sys
print sys.path
sys.path.append('...') #增加搜尋路徑,但不是永久性有效
           

加路徑的方法還有,設定環境變量PYTHON PATH,永久性的

future:使舊版python得到新版的某些特性

from _future_ import unicode_literals
from _future import division
           

5.python對象

class Student(object):
    def __init__(self,name,score):
        self.name=name
        self.score=score
    def print(self):
        print '%s,%s'%(self.name,self.score)
           

雙下劃線開頭的變量為私有變量,不可在外部通路

在Python中,變量名以雙下劃線開頭,并且以雙下劃線結尾的,是特殊變量,特殊變量是可以直接通路的,不是private變量

有些時候,你會看到以一個下劃線開頭的執行個體變量名,比如_name,這樣的執行個體變量外部是可以通路的,但是,按照約定俗成的規定,當你看到這樣的變量時,意思就是,“雖然我可以被通路,但是,請把我視為私有變量,不要随意通路”。

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)
           

多态:

在繼承中出現,當父類與子類有相同的重名函數時出現。多态意味着,不同子類在運作重名函數時,總是會 調用自身的函數

擷取對象資訊:type,isinstance,dir—擷取所有屬性和方法

type(123),isinstance('a',str)
           
  • __xxx__的屬性和方法在python裡有特殊用途,如

    __len__傳回長度。調用len()擷取對象長度時,實際上len()内部是通過該對象的__len__()方法擷取

len('ABC')  # 'ABC'.__len__()
           
  • getattr 擷取屬性
  • setattr 設定屬性
  • hasattr 判斷是否有屬性
hasattr(obj,'x')
getattr(obj,'x')
setattr(obj,'x',)  #設定屬性y,值為19
getattr(obj,'x',)  #擷取屬性x,不存在傳回404
           
  • 動态綁定屬性和方法
>> def set_score(self, score):
...     self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student)  #給Student類綁定set_score方法
           
  • __slots__:限制class的屬性,隻對目前類有作用,子類不受限制
class Student(object):
     __slots__ = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
           
  • @property能夠将方法變為屬性
class Student(object):

    @property
    def birth(self):    #把一個getattr方法變為屬性,有可讀特性
        return self._birth

    @birth.setter      #把setattr方法變為屬性,可寫特性
    def birth(self, value):
        self._birth = value

    @property         #把一個getattr方法變為屬性,可讀特性  
    def age(self):   
        return  - self._birth
           

上面的birth是可讀寫屬性,而age就是一個隻讀屬性,因為age可以根據birth和目前時間計算出來。

  • 多重繼承:一個子類繼承自多個父類,稱為Mixin
class Runnable(object):
    def run(self):
        print('Running...')

class Flyable(object):
    def fly(self):
        print('Flying...')
class Bat(Mammal, Flyable):
    pass
           
Mixin的目的就是給一個類增加多個功能,這樣,在設計類的時候,我們優先考慮通過多重繼承來組合多個Mixin的功能,而不是設計多層次的複雜的繼承關系。
           
  • 定制類:__str__,__repr__,__getitem__,__getattr__,__call__

    callabel()函數—–可判斷一對象是否是可調用對象

  • type—可以檢視一個類或變量的類型,也可以建立出新的類型,這是python動态語言的特點—–函數或類的定義在運作時建立
>>> def fn(self, name='world'): # 先定義函數
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 建立Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))  #類的類型就是type
<type 'type'>
>>> print(type(h))
<class '__main__.Hello'>
           

這裡type需要傳入三個參數:

1.class的名稱

2.繼承的父類的集合,tuple形式

3.綁定方法hello和函數fn

  • metaclass:控制類的建立行為,譯為元類。先定義metaclass,然後建立類。比較複雜,具體我也沒學會

6.錯誤處理

try:
    print 'try...'
    r =  / 
    print 'result:', r
except ZeroDivisionError, e:  #e為錯誤内容
    print 'except:', e
finally:                    #finally語句一定會被執行
    print 'finally...'  
print 'END'
           
  • logging—列印出錯誤,并且讓程式繼續運作下去
# err.py
import logging

def foo(s):
    return  / int(s)

def bar(s):
    return foo(s) * 

def main():
    try:
        bar('0')
    except StandardError, e:
        logging.exception(e)

main()
print 'END'
           
$ python err.py
ERROR:root:integer division or modulo by zero
Traceback (most recent call last):
  File "err.py", line , in main
    bar('0')
  File "err.py", line , in bar
    return foo(s) * 
  File "err.py", line , in foo
    return  / int(s)
ZeroDivisionError: integer division or modulo by zero
END
           
  • raise:抛出錯誤,抛出錯誤能抛出自己定義的,但預設抛出系統定義的
try:
     / 
except ZeroDivisionError:
    raise ValueError('input error!')   #抛出另外類型的錯誤(本來應該抛出ZeroDivisionError)
           
  • 調試:

    1.print語句

    2.assert斷言:

assert n!= 'n is zero'
           

3.logging語句,列印出錯誤日記

# err.py
import logging
logging.basicConfig(level=logging.INFO)  #指定允許記錄資訊的級别

s = '0'
n = int(s)
logging.info('n = %d' % n)
print  / n
           
$ python err.py
INFO:root:n = 
Traceback (most recent call last):
  File "err.py", line , in <module>
    print  / n
ZeroDivisionError: integer division or modulo by zero
           

4.pdb調試

5.IDE調試