1. 程式人生 > >python學習總結(函數進階)

python學習總結(函數進階)

pla 進階 empty 結合 源代碼 except 函數名 top 好的

-------------------程序運行原理-------------------
1、模塊的內建name屬性,主模塊其值為main,導入模塊其值為模塊名
1、創建時間,py文件比pyc文件新,則從新生成pyc。
2、magic num,做運行前版本測試,版本不同重新生成pyc。
3、PyCodeObject對象,源代碼中的字符串,常量值,字節碼指令,原始代碼行號的對應關系。

2、LEGB規則
1、Local :本地
當前所在命名空間(如函數,模塊),函數的參數也屬於命名空間內的變量。
2、Ecolsing function :外部嵌套函數的命名空間
外部嵌套函數的命名空間(閉包中常見)。
3、Global :全局

全局變量,函數定義所在模塊的命名空間。
4、Builtins :內建模塊命名空間
1、Python 在啟動的時候會自動為我們載入很多內建的函數、類, 比如 dict,list,type,print,這些都位於 builtins 模塊中,可以使用 dir(builtins) 來查看。
2、在Python中,有一個內建模塊,該模塊中有一些常用函數;在Python啟動後,且沒有執行程序員所寫的任何代碼前,Python會首先加載該內建函數到內存。另外,該內建模塊中的功能可以直接使用,不用在其前添加內建模塊前綴,其原因是對函數、變量、類等標識符的查找是按LEGB法則,其中B即代表內建模塊。

3、dir函數
Python 的內置函數 dir 可以用來查看一個命名空間下的所有名字符號。一個用處是查看一個命名空間的所有屬性和方法(這裏的命名空間就是指類、函數、module)。

4、垃圾回收
1、小整數對象池:
1、整數在程序中的使用非常廣泛,Python為了優化速度,使用了小整數對象池, 避免為整數頻繁申請和銷毀內存空間。
2、Python 對小整數的定義是 [-5, 257) 這些整數對象是提前建立好的,不會被垃圾回收。在一個 Python 的程序中,所有位於這個範圍內的整數使用的都是同一個對象。
2、大整數對象池:每一個大整數,均創建一個新的對象。
3、intern機制:
python中有這樣一個機制——intern機制,讓他只占用一個”HelloWorld”所占的內存空間。靠引用計數去維護何時釋放。

5、小結
1、小整數[-5,257)共用對象,常駐內存。
2、單個字符共用對象,常駐內存。

3、單個單詞,不可修改,默認開啟intern機制,共用對象,引用計數為0,則銷毀。
4、字符串(含有空格),不可修改,沒開啟intern機制,不共用對象,引用計數為0,銷毀 。
5、大整數不共用內存,引用計數為0,銷毀 。
6、註:數值類型和字符串類型在 Python 中都是不可變的,這意味著你無法修改這個對象的值,每次對變量的修改,實際上是創建一個新的對象。

6、def指令
1、def func(),在字節碼指令中就是 MAKE_FUNCTION。 Python 是動態語言,def 實際上是執行一條指令,用來創建函數 (class 則是創建類的指令),而不僅僅是個語法關鍵字。 函數並不是事先創建好的,而是執行到的時候才創建的。
2、def func() 將會創建一個名稱為 func 的函數對象。 實際上是先創建一個函數對象,然後將 func 這個名稱符號綁定到這個函數上。

7、import導入包時進行搜索路徑:
1、路徑搜索:
import sys
sys.path :查看導入包路徑
2、程序執行時導入模塊路徑
sys.path.append(‘/home/usr/local/images‘)
sys.path.insert(0,‘/home/usr/local/image‘)
3、設置linux下導入模塊路徑
echo $pythonpath
export pythonpath=$pythonpath:‘/home/usr/local/image‘
4、如果程序已經引用了模塊,但是模塊被修改。需要重新導入模塊:
可使用reload(module)進行,類似於情況緩存後進行import操作

7、pyc文件
1、概念
pyc 文件是 PyCodeObject 對象在硬盤上的表現形式。生成pyc文件:
2、pyc文件三大作用
1、創建時間,py文件比pyc文件新,則從新生成pyc文件
2、magic num做運行前版本檢測,版本不同從新生產pyc
3、PyCodeObject對象
4、在運行期間,編譯結果也就是 PyCodeObject 對象,只會存在於內存中,而當這個模塊的 Python 代碼執行完後,就會將編譯結果保存到了 pyc 文件中,這樣下次就不用編譯,直接加載到內存中。
5、這個 PyCodeObject 對象包含了 Python 源代碼中的字符串,常量值,以及通過語法解析後編譯生成的字節碼指令。PyCodeObject 對象還會存儲這些字節碼指令與原始代碼行號的對應關系,這樣當出現異常時,就能指明位於哪一行的代碼。

8、import指令
1、import 指令是用來載入 module 的,如果需要,也會順道做編譯的事。但 import 指令,還會做一件重要的事情就是把 import 的那個 module 的代碼執行一遍,這件事情很重要。 Python 是解釋執行的,連函數都是執行的時候才創建的。如果不把那個 module 的代碼執行一遍,那麽 module 裏面的函數都沒法創建,更別提去調用這些函數了。

2、執行代碼的另外一個重要作用,就是在這個 module 的命名空間中,創建模塊內定義的函數和各種對象的符號名稱(也就是變量名),並將其綁定到對象上,這樣其他 module 才能通過變量名來引用這些對象。

3、Python 虛擬機還會將已經 import 過的 module 緩存起來,放到一個全局 module 集合 sys.modules 中。 這樣做有一個好處,即如果程序的在另一個地方再次 import 這個模塊,Python 虛擬機只需要將全局 module 集合中緩存的那個 module 對象返回即可。

-------------------閉包-------------------
1、概念:
內部函數對外部函數作用域裏變量的引用(非全局變量),則稱內部函數為閉包。
2、案例:
#外部函數
def counter(start=0):
#自由變量:定義一個列表
count = [start]
#內部函數
def incr():
count[0] += 1
return count[0]#返回列表結果
#返回函數
return incr

#變量接受一個函數
con = counter(5)

#運行接收到的函數
print con()

print con()

-------------------裝飾器-------------------
1、引用通用功能處理
1、常用處理功能:
1、引入日誌
2、函數執行時間統計
3、執行函數前預備處理
4、執行函數後清洗功能
5、權限校驗等場景
6、緩存

2、案例:無參函數
#引用對應的包
from time import ctime

#修飾器
def timefun(func):
    def wrappedfunc():
        print("%s called at %s"%(func.__name__,ctime()))
        return func()
    return wrappedfunc

@timefun
def foo():
    print("I am foo")

foo()

3、案例:裝飾器和閉包混用

#coding=utf-8

from time import time

def logged(when):
    def log(f, *args, **kargs):
        print("fun:%s  args:%r  kargs:%r" %(f, args, kargs))
        #%r字符串的同時,顯示原有對象類型

    def pre_logged(f):
        def wrapper(*args, **kargs):
            log(f, *args, **kargs)
            return f(*args, **kargs)
        return wrapper

    def post_logged(f):
        def wrapper(*args, **kargs):
            now=time()
            try:
                return f(*args, **kargs)
            finally:
                log(f, *args, **kargs)
                print("time delta: %s"%(time()-now))
        return wrapper
    try:
        return {"pre":pre_logged, "post":post_logged}[when]
    except KeyError, e:
        raise ValueError(e), ‘must be "pre" or "post"‘

@logged("post")
def fun(name):
    print("%s"%(name))

fun("hello word!")

-------------------內建函數-------------------
1、概念:
1、Build-in Function,啟動python解釋器,輸入dir(builtins), 可以看到很多python解釋器啟動後默認加載的屬性和函數,這些函數稱之為內建函數, 這些函數因為在編程時使用較多,cpython解釋器用c語言實現了這些函數,啟動解釋器 時默認加載。

2、這些函數數量眾多,不宜記憶,開發時不是都用到的,待用到時再help(function), 查看如何使用,或結合百度查詢即可,在這裏介紹些常用的內建函數。

2、range
1、help(range):
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
2、參數分析:
1、start:計數從start開始。默認是從0開始。例如range(5)等價於range(0, 5)。
2、stop:到stop結束,但不包括stop.例如:range(0, 5) 是[0, 1, 2, 3, 4]沒有5。
3、step:每次跳躍的間距,默認為1。例如:range(0, 5) 等價於 range(0, 5, 1)。
3、示例:
a = range(5)
list(a)

3、map
1、help(map):
map(...)
map(function, sequence[, sequence, ...]) -> list
2、參數分析:
1、function:是一個函數
2、sequence:是一個或多個序列,取決於function需要幾個參數
3、返回值是一個list
3、語法:
參數序列中的每一個元素分別調用function函數,返回包含每次function函數返回值的list。
4、示例
#函數需要一個參數
map(lambda x: x*x, [1, 2, 3])
[1, 4, 9]

    #函數需要兩個參數
    map(lambda x, y: x+y, [1, 2, 3], [4, 5, 6])
    [5, 7, 9]

    #函數為None,相當於合並參數為元祖
    map(None, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
    [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]

    #兩個序列參數個數不一致時,個數少的補None
    map(None, [1, 3, 5, 7, 9], [2, 4, 6])
    [(1, 2), (3, 4), (5, 6), (7, None), (9, None)]

4、filter
1、help(filter):
filter(...)
filter(function or None, sequence) -> list, tuple, or string

    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.
2、參數分析:
    1、function:接受一個參數,返回布爾值True或False
    2、sequence:序列可以是str,tuple,list
3、語法
    filter函數會對序列參數sequence中的每個元素調用function函數,最後返回的結果包含調用結果為True的元素。返回值的類型和參數sequence的類型相同
4、示例
    filter(lambda x: x%2, [1, 2, 3, 4])
    [1, 3]

    filter(None, "she")
    ‘she‘

5、reduce
1、help(reduce):
reduce(...)
reduce(function, sequence[, initial]) -> value

        Apply a function of two arguments cumulatively to the items of a sequence,
        from left to right, so as to reduce the sequence to a single value.
        For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
        ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
        of the sequence in the calculation, and serves as a default when the
        sequence is empty.
2、參數分析:
    1、function:該函數有兩個參數
    2、sequence:序列可以是str,tuple,list
    3、initial:固定初始值

3、語法
    reduce依次從sequence中取一個元素,和上一次調用function的結果做參數再次調用function。 第一次調用function時,如果提供initial參數,會以sequence中的第一個元素和initial 作為參數調用function,否則會以序列sequence中的前兩個元素做參數調用function。 註意function函數不能為None。
4、示例
    reduce(lambda x, y: x+y, [1,2,3,4])
    10

    reduce(lambda x, y: x+y, [1,2,3,4], 5)
    15

    reduce(lambda x, y: x+y, [‘aa‘, ‘bb‘, ‘cc‘], ‘dd‘)
    ‘ddaabbcc‘

6、sorted
1、help(sorted):
sorted(...)
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
2、參數分析:
自定義cmp比較函數,返回三種情況:
x<y 返回-1
x>y 返回1
x==y 返回0
3、示例
def cmp_ignore_case(s1, s2):
u1 = s1.upper()
u2 = s2.upper()
if u1 < u2:
return -1
if u1 > u2:
return 1
return

-------------------叠代器-------------------
1、概念:
叠代器僅是一容器對象,它實現了叠代器協議。

2、next():
1、返回容器的下一個元素
2、在結尾時引發Stoplteration異常

3、iter():
數據通過iter轉換為跌打器的格式,返回跌打器自身

-------------------生成器-------------------
1、概念:
生成器是這樣一個函數,它記住上一次返回時在函數體中的位置。對生成器函數的第二次(或第 n 次)調用跳轉至該函數中間,而上次調用的所有局部變量都保持不變。

2、特點:
1.生成器是一個函數,而且函數的參數都會保留。
2.叠代到下一次的調用時,所使用的參數都是第一次所保留下的,即是說,在整個所有函數調用的參數都是第一次所調用時保留的,而不是新創建的
3.節約內存

3、案例:
#generation.py
def gen():
for x in xrange(4):
tmp = yield x
if tmp == "hello":
print "world"
else:
print "itcastcpp ", str(tmp)

#執行到yield時,gen函數作用暫時保存,返回x的值;tmp接收下次c.send("python"),send發送過來的值,c.next()等價c.send(None)

>>>from generation import gen
>>>c=gen()
>>>c.next()
0
>>>c.next()
itcastcpp None
1
>>>c.send("python")
itcastcpp python
2

4、應用場景:
1、當需要一個非常大的列表時,為了減少內存消耗,可以使用生成器
案例:
class A(object):
def init(self, i):
from time import sleep, time
sleep(i)
print (time())

    1、for c in [A(i) for i in range(5)] :[]是通過遍歷可叠代對象生成一個list
    2、for c in (A(i) for i in range(5)) :()是直接返回可叠代對象

5、小結:
1、無限遞歸成為可能
2、極大的降低了線程或進程間上下文切換的開銷
3、用戶手工指定線程調用,避免了鎖開銷

-------------------上下文-------------------

-------------------functools函數-------------------
1、概念:
functools 是python2.5被引人的,一些工具函數放在此包裏。

2、操作:
1、import functools :引用對應的包
2、dir(functools) :查看包中對應的工具函數

1、partial函數(偏函數):
1、概念:
把一個函數的某些參數設置默認值,返回一個新的函數,調用這個新函數會更簡單。
2、示例:
import functools
def showarg(*args, **kw):
print(args)
print(kw)

    p1=functools.partial(showarg, 1,2,3)
    p1()
    p1(4,5,6)
    p1(a=‘python‘, b=‘itcast‘)

    p2=functools.partial(showarg, a=3,b=‘linux‘)
    p2()
    p2(1,2)
    p2(a=‘python‘, b=‘itcast‘)

2、wraps函數:
1、概念:
使用裝飾器時,有一些細節需要被註意。例如,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變)。Python的functools包中提供了一個叫wraps的裝飾器來消除這樣的副作用
2、示例:
import functools
def note(func):
"note function"@functools.wraps(func)
br/>@functools.wraps(func)
"wrapper function"
print(‘note something‘)
return func()
return wrapper

    @note
    def test():
        "test function"
        print(‘I am test‘)

    test()
    print(test.__doc__)

python學習總結(函數進階)