py學習筆記2-函式
阿新 • • 發佈:2018-12-22
函式語法
def power(x): return x*x # enroll('Bob', 'M', 7) # enroll('Adam', 'M', city='Tianjin') def enroll(name, gender, age=6, city='Beijing'): print('name:', name) print('gender:', gender) print('age:', age) print('city:', city) # L 是一個已經被計算出的引數, 預設引數應該指向不變的物件 def add_end(L=[]): L.append('END') return L # >>> add_end() # ['END', 'END'] # >>> add_end() # ['END', 'END', 'END'] # 改進如下 def add_end(L=None): if L is None: L = [] L.append('END') return L # calc(1, 3, 5, 7) numbers會被作為一個 list 解析 def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum def person(name,age,**kw): print('name:', name, 'age:', age, 'other:', kw) # >>> person('Bob', 35, city='Beijing') # name: Bob age: 35 other: {'city': 'Beijing'} # >>> person('Adam', 45, gender='M', job='Engineer') # name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} # 命名關鍵字引數需要一個特殊分隔符*,*後面的引數被視為命名關鍵字引數 def person(name, age, *, city, job): print(name, age, city, job) # >>> person('Jack', 24, city='Beijing', job='Engineer') # Jack 24 Beijing Engineer def f1(a, b, c=0, *args, **kw): print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw) def f2(a, b, c=0, *, d, **kw): print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw) >>> f1(1, 2) a = 1 b = 2 c = 0 args = () kw = {} >>> f1(1, 2, c=3) a = 1 b = 2 c = 3 args = () kw = {} >>> f1(1, 2, 3, 'a', 'b') a = 1 b = 2 c = 3 args = ('a', 'b') kw = {} >>> f1(1, 2, 3, 'a', 'b', x=99) a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99} >>> f2(1, 2, d=99, ext=None) a = 1 b = 2 c = 0 d = 99 kw = {'ext': None} >>> args = (1, 2, 3, 4) >>> kw = {'d': 99, 'x': '#'} >>> f1(*args, **kw) a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'} >>> args = (1, 2, 3) >>> kw = {'d': 88, 'x': '#'} >>> f2(*args, **kw) a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
函數語言程式設計
函式名本身就是一個變數,指向一個函式,因此函式也可以作為變數使用賦值給其他變數
map
def f(x):
return x*x
arr = [1,2,3,4,5]
ir = map(f,arr)
print(list(ir))
map(fun,Iterable) 它將會把 fun 用在 Iterable 每一個元素上,生成一個迭代器 Iterator,Ierator 是惰性的,用 list(Iterator) 將強制生成一個 Iterable
reduce
map 只能傳入一個引數,如果我們想傳入兩個引數呢
在 Python3 中,reduce() 函式已經被從全域性名字空間裡移除了,它現在被放置在 fucntools 模組裡,如果想要使用它,則需要通過引入 functools 模組來呼叫 reduce() 函式
from functools import reduce
def sum(x,y):
return x + y
print(reduce(sum,[1,2,3,4,5])) # return sum(sum(sum(sum(1,2),3),4),5)
filter
filter()把傳入的函式依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素
def is_odd(v): return v % 2 == 0 f = filter(is_odd,[1,2,3,4,5]) print(list(f))
filter 得到的也是一個惰性的 Iterator
sorted
key指定的函式將作用於list的每一個元素上,並根據key函式返回的結果進行排序,並按照對應關係返回list相應的元素
print(sorted([-5,-88,9,4,33,84]))
print(sorted([-5,-88,9,4,33,84],key=abs))
print(sorted([-5,-88,9,4,33,84],key=abs,reverse=False))
print(sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower))
# [-88, -5, 4, 9, 33, 84]
# [4, -5, 9, 33, 84, -88]
# [4, -5, 9, 33, 84, -88]
# ['about', 'bob', 'Credit', 'Zoo']
閉包
def lazy_sum(*args):
def sum():
n = 0
for v in args:
n += v
return n
return sum
s = lazy_sum(1,2,3,4,5,6,7,8,9)
print(s()) # 45 閉包與惰性求和
匿名函式
f = lambda x: x*x
def fun(x):
return x*x
如上,兩個函式等價
裝飾器
所有的函式都可以通過 fun.name 得到定義時的函式名,即使被賦值給其他變數,也會得到原來的函式名
def log(fun):
def warpper(*args,**kw): # 對原來的函式進行包裝,類似於切面
print('like sprint aop')
fun(*args,**kw)
return warpper
def p(*args,**kw):
for v in args:
print(v)
f = log(p)
f(1,2,3)
我們首先建立了一個函式修飾器,它為函式的功能做了擴充,然後傳入要被裝飾的函式,並得到一個被裝飾後的函式並呼叫它
使用 python 的語法糖可以簡化這一過程
def log(fun):
def warpper(*args,**kw):
print('like sprint aop')
fun(*args,**kw)
return warpper
@log # 相當於 p = log(p)
def p(*args,**kw):
for v in args:
print(v)
p(1,2,3)
在做包裝時傳入引數
import functools
def log(b,l):
def decorator(func):
def warpper(*args,**kw):
print(b,' middle ',l)
func(*args,**kw)
return warpper
return decorator
@log('begin','last') # 等同於 p = log('begin','last')(p),兩層修飾
def p(*args,**kw):
for v in args:
print(v)
print(p.__name__) # warpper 其實現在的 p 是指向 warpper 函式的,我們要修改回來,避免出問題
p.__name__ = p
p(1,2,3,a='a')
# 修改後的函式如下
def log(b,l):
def decorator(func):
@functools.wraps(func)
def warpper(*args,**kw):
print(b,' middle ',l)
func(*args,**kw)
return warpper
return decorator
偏函式
py 提供的內建函式大多都可以傳入其他引數以滿足需求,如果每次呼叫都需要傳入一個額外引數,我們可以把這引數固定下來
import functools
print(int('12345'))
print(int('01011',base=2))
def int2(x):
return int(x,base=2)
print(int2('001010'))
int2 = functools.partial(int,base=2) # 和上面 int2 的效果相同