1.1.函數(shù)定義
1.1.1.定義一個(gè)函數(shù)
1.1python定義函數(shù)用def關(guān)鍵字,一般格式如下
def 函數(shù)名(參數(shù)列表):
函數(shù)體
1.2函數(shù)名的命名規(guī)則
形參:形式參數(shù)秦躯,不是實(shí)際存在被啼,是虛擬變量。在定義函數(shù)和函數(shù)體的時(shí)候使用形參端姚,目的是在函數(shù)調(diào)用時(shí)接收實(shí)參(實(shí)參個(gè)數(shù),類型與實(shí)參一一對(duì)應(yīng))
實(shí)參:實(shí)際參數(shù)盾戴,調(diào)用函數(shù)時(shí)傳給函數(shù)的參數(shù)寄锐,可以是常量,變量尖啡,表達(dá)式橄仆,函數(shù),傳給形參
區(qū)別:形參是虛擬的衅斩,不占用內(nèi)存空間盆顾,形參變量只有在被調(diào)用時(shí)才分配內(nèi)存單元,實(shí)參是一個(gè)變量畏梆,占用內(nèi)存空間您宪,數(shù)據(jù)傳送單向,實(shí)參傳給形參奠涌,不能形參傳給實(shí)參
def area(width,height):
return width*height
w = 4
h = 5
print(area(w,h))
20
width和height是形參宪巨,w=4和h=5是實(shí)參。
1.1.2.使用函數(shù)的好處
1代碼重用2便于修改溜畅,易擴(kuò)展
msg = 'abcdefg'
msg = msg[:2] + 'z' + msg[3:]
print(msg)
msg = '1234567'
msg = msg[:2] + '9' + msg[3:]
print(msg)
改進(jìn)
def setstr(msg,index,char):
return msg[:index] + 'char' + msg[index+1:]
msg = 'abcdefg'
setstr(msg,2,'z')
print(msg)
msg = '1234567'
setstr(msg,2,'9')
print(msg)
1.2.函數(shù)的參數(shù)
- 必需參數(shù)
- 關(guān)鍵字參數(shù)
- 默認(rèn)參數(shù)
- 不定長(zhǎng)參數(shù)
1.2.1.必需參數(shù):
必需參數(shù)須以正確的順序傳入函數(shù)捏卓。調(diào)用時(shí)的數(shù)量必須和聲明時(shí)的一樣
def f(name,age):
print('I am %s,I am %d'%(name,age))
f('alex',18)
f('alvin',16)
I am alex,I am 18
I am alvin,I am 16
1.2.2.關(guān)鍵字參數(shù):
關(guān)鍵字參數(shù)和函數(shù)調(diào)用關(guān)系緊密,函數(shù)調(diào)用使用關(guān)鍵字參數(shù)來確定傳入的參數(shù)值慈格。使用關(guān)鍵字參數(shù)允許函數(shù)調(diào)用時(shí)參數(shù)的順序與聲明時(shí)不一致怠晴,因?yàn)閜ython解釋器能夠用參數(shù)名匹配參數(shù)值。
def f(name,age):
print('I am %s,I am %d'%(name,age))
f(age = 16,name = 'alvin')
I am alvin,I am 16
1.2.3.默認(rèn)參數(shù)
調(diào)用函數(shù)時(shí)浴捆,缺少參數(shù)的值如果沒有傳入蒜田,則被認(rèn)為是默認(rèn)值。下例會(huì)打印默認(rèn)的sex选泻,如果sex沒有被傳入:
def print_info(name,age,sex = 'male'):
print('Name:%s' % name)
print('age:%s' % age)
print('sex:%s' % sex)
return
print_info('alex',18)
print_info('鐵錘',40,'female')
Name:alex
age:18
sex:male
Name:鐵錘
age:40
sex:female
1.2.4.不定長(zhǎng)參數(shù)
你可能需要一個(gè)函數(shù)能處理比當(dāng)初聲明時(shí)更多的參數(shù)冲粤。這些參數(shù)叫做不定長(zhǎng)參數(shù)美莫,和上述2眾參數(shù)不同,聲明時(shí)不會(huì)命名色解。
def add(*tuples):
sum = 0
for v in tuples:
sum += v
return sum
print(add(1,4,6,9))
print(add(1,4,6,9,5))
20
25
加了星號(hào)的變量名會(huì)存放所有未命名的變量參數(shù)茂嗓,而加兩個(gè)星號(hào)的變量名會(huì)存放命名的變量參數(shù)
def print_info(**kwargs):
print(kwargs)
for i in kwargs:
print('%s:%s'%(i,kwargs[i])) #根據(jù)參數(shù)可以打印任意相關(guān)信息了
return
print_info(name = 'alex',age = 18,sex = 'female',hobby = 'girl',nationlity = 'Chinese',ability = 'Python')
{'name': 'alex', 'age': 18, 'sex': 'female', 'hobby': 'girl', 'nationlity': 'Chinese', 'ability': 'Python'}
name:alex
age:18
sex:female
hobby:girl
nationlity:Chinese
ability:Python
注意餐茵,還可以這樣傳參:
def f(*args):
print(args)
f(*[1,2,5])
def f(**kwargs):
print(kwargs)
f(**{'name':'alex'})
(1, 2, 5)
{'name': 'alex'}
PyCharm 的調(diào)試工具
- F8 Step Over 可以單步執(zhí)行代碼科阎,會(huì)把函數(shù)調(diào)用看做是一行代碼直接執(zhí)行
- F7 Step Into 可以單步執(zhí)行代碼,如果是函數(shù)忿族,會(huì)進(jìn)入函數(shù)內(nèi)部
1.3.函數(shù)的返回值
要想獲得函數(shù)的執(zhí)行結(jié)果锣笨,就可以用return語句把結(jié)果返回
注意:
函數(shù)在執(zhí)行過程中只要遇到return語句,就會(huì)停止執(zhí)行并返回結(jié)果道批,所以也可理解為return語句代表著函數(shù)的結(jié)束错英,如果未在函數(shù)中指定return,那這個(gè)函數(shù)的返回值為None
return多個(gè)對(duì)象隆豹,解釋器會(huì)把這多個(gè)對(duì)象組裝成一個(gè)元組作為一個(gè)一個(gè)整體結(jié)果輸出椭岩。
def sum_and_avg(list):
sum = 0
count = 0
for e in list:
#如果元素e是數(shù)值
if isinstance(e,int) or isinstance(e,float):
count += 1
sum += e
return sum,sum / count
my_list = [20,15,2.8,'a',35,5.9,-1.8]
#獲取sum_and_avg函數(shù)返回的多個(gè)值,多個(gè)返回值被封裝成元組
tp = sum_and_avg(my_list)
print(tp)
20 20.0
1.4.高階函數(shù)
高階函數(shù)是至少滿足下列一個(gè)條件的函數(shù):
接受一個(gè)或多個(gè)函數(shù)作為輸入 輸出一個(gè)函數(shù)
def add(x,y,f):
return f(x) + f(y)
res = add(3,-6,abs)
print(res)
9
def method():
x = 2
def double(n):
return n*x
return double
fun = method()
num = fun(20)
print(num)
40
1.5.函數(shù)作用域
1.5.1.作用域介紹
python中的作用域分4種情況:
L:local璃赡,局部作用域判哥,即函數(shù)中定義的變量;
E:enclosing碉考,嵌套的父級(jí)函數(shù)的局部作用域塌计,即包含此函數(shù)的上級(jí)函數(shù)的局部作用域,但不是全局的侯谁;
G:global锌仅,全局變量,就是模塊級(jí)別定義的變量墙贱;
B:builtin热芹,系統(tǒng)固定模塊里面的變量,比如int,bytearray等惨撇。
搜索變量的優(yōu)先級(jí)順序依次是:作用域局部>外層作用域>當(dāng)前模塊中的全局>python內(nèi)置作用域伊脓,也就是LEGB。
x = str(100)#int built-in
print('hello' + x)
str = 33#str內(nèi)置函數(shù)被破壞串纺,一定不要這樣做
print(str)
g_count = 0#global
def outer():
o_count = 1#enclosing
def inner():
i_count = 2#local
print(o_count)
#print(i_count)找不到
inner()
outer()
當(dāng)然丽旅,local和enclosing是相對(duì)的,enclosing
變量相對(duì)上層來說也是local纺棺。
1.5.2.作用域產(chǎn)生
在python中榄笙,只有模塊(module),類(class)以及函數(shù)(def,lambda)才會(huì)引入新的作用域祷蝌,其他的代碼塊(如if茅撞、try、for等)是不會(huì)引入新的作用域的,如下代碼:
if 2 > 1:
x = 1
print(x)
1
這個(gè)是沒有問題的米丘,if并沒有引入一個(gè)新的作用域剑令,x仍處在當(dāng)前作用域中,后面代碼可以使用拄查。
def text():
x = 2
print(x)
NameError: name 'x' is not defined
def吁津、class、lambda是可以引入新作用域的堕扶。
1.5.3.變量的修改
x = 6
def f2():
print(x)
x = 5
f2()
#錯(cuò)誤的原因在于print(x)時(shí)碍脏,解釋器會(huì)在局部作用域找,會(huì)找到x=5(函數(shù)已經(jīng)加載到內(nèi)存)稍算,但x使用在聲明前了典尾,所以報(bào)錯(cuò);
#local varible 'x' referenced before assignment.如何證明找到了x=5呢糊探?簡(jiǎn)單:注釋掉x=5,x=6
#報(bào)錯(cuò)為:name 'x' is not defined
#同理
x = 6
def f2():
x += 1
f2()
報(bào)錯(cuò)為:UnboundLocalError: local variable 'x' referenced before assignment
1.5.4.global關(guān)鍵字
當(dāng)內(nèi)部作用域想修改外部作用域的變量時(shí)钾埂,就要用到global和nonlocal關(guān)鍵字了,當(dāng)修改的變量是在全局作用域(global作用域)上的科平,就要使用global先聲明一下褥紫,代碼如下:
count = 10
def outer():
global count
print(count)
count = 100
print(count)
outer()
10
100
1.5.5.nonlocal關(guān)鍵字
global關(guān)鍵字聲明的變量必須在全局作用域上,不能嵌套作用域上匠抗,當(dāng)要修改嵌套作用域(enclosing作用域故源,外層非全局作用域)中的變量怎么辦呢,這時(shí)就需要nonlocal關(guān)鍵字了汞贸。
def outer():
count = 10
def inner():
nonlocal count
count = 20
print(count)
inner()
print(count)
outer()
20
20
1.5.6.小結(jié)
(1)變量查找順序:LEGB绳军,作用域局部>外層作用域>當(dāng)前模塊中的全局>python內(nèi)置作用域;
(2)只有模塊矢腻、類及函數(shù)才能引入新作用域门驾;
(3)對(duì)于一個(gè)變量,內(nèi)部作用域先聲明就會(huì)覆蓋外部變量多柑,不聲明直接使用奶是,就會(huì)使用外部作用域的變量;
(4)內(nèi)部作用域要修改外部作用域變量的值時(shí)竣灌,全局變量要使用global關(guān)鍵字聂沙,嵌套作用域變量要使用nonlocal關(guān)鍵字。nonlocal是python3新增的關(guān)鍵字初嘹,有了這個(gè)關(guān)鍵字及汉,就能完美地實(shí)現(xiàn)閉包了。
1.6.遞歸函數(shù)
定義:在函數(shù)內(nèi)部屯烦,可以調(diào)用其他函數(shù)坷随。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身房铭,這個(gè)函數(shù)就是遞歸函數(shù)。
1.6.1.例1(階乘)
def factorial(n):
result = n
for i in range(1,n):
result *= 1
return result
print(factorial(4))
#****************遞歸****************
def factorial_new(n):
if n == 1:
return 1
return n*factorial_new(n-1)
print(factorial_new(3))
1.6.2.例2(斐波那契數(shù)列)
def fibo(n):
before = 0
after = 1
for i in range(n-1):
ret = before + after
before = after
after = ret
return ret
print(fibo(3))
#*************遞歸************
def fibo_new(n): #n可以為零温眉,數(shù)列有[0]
if n <= 1:
return n
return(fibo_new(n-1) + fibo_new(n-2))
print(fibo_new(3))
print(fibo_new(30000))#maximum recursion depth exceeded in comparison 遞歸函數(shù)的優(yōu)點(diǎn):是定義簡(jiǎn)單缸匪,邏輯清晰。理論上类溢,所有的遞歸函數(shù)都可以寫成循環(huán)的方式更鲁,但循環(huán)的邏輯不如遞歸清晰筛欢。
1.6.3.遞歸特性:
1.必須有一個(gè)明確的結(jié)束條件
2.每次進(jìn)入更深一層遞歸時(shí)荠诬,問題規(guī)模相比上次遞歸都應(yīng)有所減少
3.遞歸效率不高汁蝶,遞歸層次過多會(huì)導(dǎo)致棧溢出(在計(jì)算機(jī)中,函數(shù)調(diào)用是通過棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的窃躲,每當(dāng)進(jìn)入一個(gè)函數(shù)調(diào)用,棧就會(huì)加一層棧幀钦睡,每當(dāng)函數(shù)返回蒂窒,棧就會(huì)減一層棧幀。由于棧的大小不是無限的荞怒,所以洒琢,遞歸調(diào)用的次數(shù)過多,會(huì)導(dǎo)致棧溢出)
1.7.匿名函數(shù)
匿名函數(shù)就是不需要顯式的指定函數(shù)名褐桌。
關(guān)鍵字lambda表示匿名函數(shù)衰抑,冒號(hào)前面的n表示函數(shù)參數(shù),可以有多個(gè)參數(shù)荧嵌。
匿名函數(shù)有個(gè)限制呛踊,就是只能有一個(gè)表達(dá)式,不用寫return啦撮,返回值就是該表達(dá)式的結(jié)果谭网。
用匿名函數(shù)有個(gè)好處,因?yàn)楹瘮?shù)沒有名字赃春,不必?fù)?dān)心函數(shù)名沖突愉择。此外,匿名函數(shù)也是一個(gè)函數(shù)對(duì)象织中,也可以把匿名函數(shù)賦值給一個(gè)變量锥涕,再利用變量來調(diào)用該函數(shù)。
有些函數(shù)在代碼中只用一次狭吼,而且函數(shù)體比較簡(jiǎn)單层坠,使用匿名函數(shù)可以減少代碼量,看起來比較“優(yōu)雅”搏嗡。
def calc(x,y):
return x**y
#換成匿名函數(shù)
calc = lambda x,y:x**y
print(calc(2,5))
def calc(x,y):
if x > y:
return x*y
else:
return x / y
#三元運(yùn)算換成匿名函數(shù)
calc = lambda x,y:x * y if x > y else x / y
print(calc(2,5))
32
0.4
匿名函數(shù)主要與其他函數(shù)聯(lián)合使用
1.8.內(nèi)置函數(shù)
1.8.1.map函數(shù)
map()函數(shù)接收兩個(gè)參數(shù)窿春,一個(gè)是函數(shù)拉一,一個(gè)是Iterable,map將傳入的函數(shù)依次作用到序列的每個(gè)元素旧乞,并把結(jié)果作為新的Iterator返回
遍歷序列蔚润,對(duì)序列中每個(gè)元素進(jìn)行函數(shù)操作,最終獲取新的序列尺栖。
求列表[1,2,3,4,5,6,7,8,9]嫡纠,返回一個(gè)n*n的列表
#一般解決方案
li = [1,2,3,4,5,6,7,8,9]
for ind,val in enumerate(li):
li[ind] = val * val
print(li)
#高級(jí)解決方案
li = [1,2,3,4,5,6,7,8,9]
print(list(map(lambda x:x*x,li)))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
1.8.2.reduce函數(shù)
reduce把一個(gè)函數(shù)作用在一個(gè)序列[x1,x2,x3,...]上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù)延赌,reduce把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積運(yùn)算除盏,其效果就是:
reduce(func,[1,2,3])等同于func(func(1,2),3)
對(duì)于序列內(nèi)所有元素進(jìn)行累計(jì)操作
#接受一個(gè)list并利用reduce()求積
from functools import reduce
li = [1,2,3,4,5,6,7,8,9]
print(reduce(lambda x,y:x * y,li))
362880
1.8.3.filter函數(shù)
filter()也接收一個(gè)函數(shù)和一個(gè)序列。和map()不同的是挫以,filter()把傳入的函數(shù)依次作用于每個(gè)元素者蠕,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
對(duì)于序列中的元素進(jìn)行篩選掐松,最終獲取符合條件的序列
li = [1,2,3,4,5,6,9,10,15]
print(list(filter(lambda x:x % 2==1,li)))
#回?cái)?shù)是指從左向右讀和從右向左讀都是一樣的數(shù)踱侣,例如12321,909.請(qǐng)利用filter()篩選出回?cái)?shù)
li = list(range(1,200))
print(list(filter(lambda x:int(str(x)) == int(str(x)[::-1]),li)))
[1, 3, 5, 9, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
1.8.4.sorted函數(shù)
sorted(iterable,/,*,key=None,reverse=False)
接收一個(gè)key函數(shù)來實(shí)現(xiàn)對(duì)可迭代對(duì)象進(jìn)行對(duì)象進(jìn)行自定義的排序
可迭代對(duì)象:主要與列表,字符串大磺,元組抡句,集合和字典
key:接收一個(gè)函數(shù),根據(jù)此函數(shù)返回的結(jié)果杠愧,進(jìn)行排序
reverse:排序方向待榔,默認(rèn)為從小到大,reverse=True為逆向
li = [-21,-12,5,9,36]
print(sorted(li,key = lambda x:abs(x)))
[5, 9, -12, -21, 36]
li = ['bad','about','Zoo','Credit']
print(sorted(li,key=lambda x:x[0]))
"""
對(duì)字符串排序流济,是按照ASCII的大小比較的锐锣,由于‘Z’<‘a(chǎn)',結(jié)果,大寫字母z會(huì)排在小寫字母a的前面袭灯。
"""
['Credit', 'Zoo', 'about', 'bad']
L = [('Bob',75),('Adam',92),('Bart',66),('Lisa',88)]
#調(diào)用sorted()對(duì)上述列表分別按名字排序
print(sorted(L,key=lambda x:x[0]))
#再按成績(jī)從高到低排序
print(sorted(L,key=lambda x:x[1],reverse=True))
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
1.9.函數(shù)式編程
學(xué)會(huì)了上面幾個(gè)重要的函數(shù)過后刺下,我們就可以來聊一聊函數(shù)式編程了。
--概念(函數(shù)式編程)函數(shù)式編程是一種編程范式稽荧,我們常見的編程范式有命令式編程橘茉,函數(shù)式編程,常見的面向?qū)ο缶幊桃彩且环N命令式編程姨丈。
命令式編程是面向計(jì)算機(jī)硬件的抽象畅卓,有變量(對(duì)應(yīng)著存儲(chǔ)單元),賦值語句(獲取蟋恬,存儲(chǔ)指令)翁潘,表達(dá)式(內(nèi)存引用和算術(shù)運(yùn)算)和控制語句(跳轉(zhuǎn)指令),一句話歼争,命令式程序就是一個(gè)馮諾依曼機(jī)的指令序列拜马。
而函數(shù)式編程是面向數(shù)學(xué)的抽象渗勘,將計(jì)算機(jī)描述為一種表達(dá)式求值,一句話俩莽,函數(shù)式編程就是一個(gè)表達(dá)式旺坠。
函數(shù)式編程的本質(zhì)
函數(shù)式編程中的函數(shù)這個(gè)術(shù)語不是指計(jì)算機(jī)中的函數(shù),而是指數(shù)學(xué)中的函數(shù)扮超,即自變量的映射取刃。也就是說一個(gè)函數(shù)的值僅決定于函數(shù)參數(shù)的值,不依賴其他狀態(tài)出刷。比如y=x*x函數(shù)計(jì)算x的平方璧疗,只要x的平方,不論什么時(shí)候調(diào)用馁龟,調(diào)用幾次崩侠,值都是不變的。
純函數(shù)式編程語言中的變量也不是命令式編程語言中的變量屁柏,即存儲(chǔ)狀態(tài)的單元啦膜,而是代數(shù)中的變量,即一個(gè)值的名稱淌喻。變量的值時(shí)不可變的,也就是說不允許像命令式編程語言中那樣多次給一個(gè)變量賦值雀摘。比如說在命令式編程語言我們寫“x=x+1”,這依賴可變狀態(tài)的事實(shí)裸删。
函數(shù)式語言的如條件語句,循環(huán)語句也不是命令式編程語言中的控制語句阵赠,而是函數(shù)的語法涯塔。
嚴(yán)格意義上的函數(shù)式編程意味著不使用可變的變量,賦值清蚀,循環(huán)和其他命令式控制結(jié)構(gòu)進(jìn)行編程匕荸。
函數(shù)式編程關(guān)心數(shù)據(jù)的映射,命令式編程關(guān)心解決問題的步驟枷邪,這也是為什么“函數(shù)式編程”叫做“函數(shù)式編程”榛搔。
實(shí)例:現(xiàn)在,讓你把number=[2,-5,9,-7,2,5,4,-1,0,-3,8]中的正數(shù)的平均值东揣,你肯定可以寫出:
算數(shù)組中正整數(shù)的平均值
number = [2,-5,9,-7,2,5,4,-1,0,-3,8]
count = 0
sum = 0
for i in range(len(number)):
if number[i] > 0:
count += 1
sum += number[i]
print(sum,count)
if count > 0:
average = sum/count
print(average)
30 6
5
首先循環(huán)列表中的值践惑,累計(jì)次數(shù),并對(duì)大于0的數(shù)進(jìn)行累加嘶卧,最后求取平均值尔觉。
這就是命令式編程--你要做什么事情,你得把達(dá)到目的的步驟詳細(xì)的描述出來芥吟,然后交給機(jī)器去運(yùn)行侦铜。
這也正是命令式編程的理論模型--圖靈機(jī)的特點(diǎn)专甩。一條寫滿數(shù)據(jù)的紙帶,一條根據(jù)紙帶內(nèi)容運(yùn)動(dòng)的機(jī)器钉稍,機(jī)器每動(dòng)一步都需要紙帶上寫著如何達(dá)到涤躲。
那么,不用這種方式如何做到呢嫁盲?
number = [2,-5,9,-7,2,5,4,-1,0,-3,8]
positive = filter(lambda x:x>0,number)
average = reduce(lambda x,y:x+y,positive)/len(positive)
print(average)
5
1.10.將函數(shù)存儲(chǔ)在模塊中
函數(shù)的優(yōu)點(diǎn)之一是篓叶,使用它們可將代碼塊與主程序分離。通過給函數(shù)指定描述性名稱羞秤,可讓主程序容易理解得多缸托。你還可以更近一步,講函數(shù)存儲(chǔ)在被稱為模塊的獨(dú)立文件中瘾蛋,再將模塊導(dǎo)入到主程序中俐镐。import語句允許在當(dāng)前運(yùn)行的程序文件中使用模塊中的代碼。
通過將函數(shù)存儲(chǔ)在獨(dú)立的文件中哺哼,可隱藏程序代碼的細(xì)節(jié)佩抹,將重點(diǎn)放在程序的高層邏輯上。這還能讓你在與眾不同的程序中重用函數(shù)取董。將函數(shù)存儲(chǔ)在獨(dú)立文件中棍苹,可與其他程序員共享這些文件而不是整個(gè)程序。知道如何導(dǎo)入函數(shù)還能讓你使用其他程序員編寫的函數(shù)庫茵汰。
導(dǎo)入模塊的方法有多種枢里,下面對(duì)每種都作簡(jiǎn)要的介紹。
1.10.1.導(dǎo)入整個(gè)模塊
要讓函數(shù)是可導(dǎo)入的蹂午,得先創(chuàng)建模塊栏豺。模塊是擴(kuò)展名為.py的文件,包含要導(dǎo)入到程序中的代碼豆胸。下面來創(chuàng)建一個(gè)包含函數(shù)make_pizza()的模塊奥洼。
pizza.py
def make_pizza(size,*toppings):
"""
概述要制作的比薩
:param size:
:param toppings:
:return:
"""
print("\nMaking a" + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("-" + topping)
接下來,我們?cè)趐izza.py所在的目錄中創(chuàng)建另一個(gè)名為making_pizzas.py的文件晚胡,這個(gè)文件導(dǎo)入剛創(chuàng)建的模塊灵奖,再調(diào)用make_pizza()兩次:
making_pizzas.py
import pizza
pizza.make_pizza(16,'peppperoni')
pizza.make_pizza(12,'mushrooms','green peppers','extra cheese')
python讀取這個(gè)文件時(shí),代碼行import pizza讓python打開文件pizza.py搬泥,并將其中的所有函數(shù)都復(fù)制到這個(gè)程序中桑寨。你看不到復(fù)制的代碼,因?yàn)檫@個(gè)程序運(yùn)行時(shí)忿檩,python在幕后復(fù)制這些代碼尉尾。你只需知道,在making_pizzas.py中燥透,可以使用pizza.py中定義的所有函數(shù)沙咏。
Making a16-inch pizza with the following toppings:
-peppperoni
Making a12-inch pizza with the following toppings:
-mushrooms
-green peppers
-extra cheese
這就是一種導(dǎo)入方法:只需編寫一條import語句并在其中指定模塊名辨图,就可在程序中使用該模塊中的所有函數(shù)。如果你使用這種import語句導(dǎo)入了名為module_name.py的整個(gè)模塊肢藐,就可使用下面的語法來使用其任何一個(gè)函數(shù):
_module_name.function_name_()
1.10.2.導(dǎo)入特定的函數(shù)
你還可以導(dǎo)入模塊中的特定函數(shù)故河,這種導(dǎo)入方法的語法如下:
from _module_name_ import _function_name_
通過用逗號(hào)分隔函數(shù)名,可根據(jù)需要從模塊中導(dǎo)入任意數(shù)量的函數(shù):
from _module_name_ import _function_0,function_1,function_2_
對(duì)于前面的making_pizzas.py示例吆豹,如果只想導(dǎo)入要使用的函數(shù)鱼的,代碼將類似于下面這樣:
from pizza import make_pizza
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','exrta cheese')
若使用這種語法,調(diào)用函數(shù)時(shí)就無需使用句點(diǎn)痘煤。由于我們?cè)趇mport語句中顯式地導(dǎo)入函數(shù)make_pizza()凑阶,因此調(diào)用它時(shí)只需指定其名稱。
1.10.3.使用as給函數(shù)指定別名
如果要導(dǎo)入的函數(shù)的名稱可能與程序中現(xiàn)有的名稱沖突衷快,或者函數(shù)的名稱太長(zhǎng)宙橱,可指定簡(jiǎn)短而獨(dú)一無二的別名--函數(shù)的另一個(gè)名稱,類似于外號(hào)蘸拔。要給函數(shù)指定這種特殊外號(hào)师郑,需要在導(dǎo)入它時(shí)這樣做。
下面給函數(shù)make_pizza()指定了別名mp()调窍。這是在import語句中使用make_pizza/as mp實(shí)現(xiàn)的宝冕,關(guān)鍵字as將函數(shù)重名為你提供的別名:
from pizza import make_pizza as mp
mp(16,'pepperoni')
mp(12,'mushrooms','green peppers','exrta cheese')
上面的import語句將函數(shù)make_pizza()重命名為mp();在這個(gè)程序中邓萨,每當(dāng)需要調(diào)用make_pizza()時(shí)猬仁,都可簡(jiǎn)寫成mp(),而python將運(yùn)行make_pizza()中的代碼先誉,這可避免與這個(gè)程序可能包含的函數(shù)make_pizza()混淆。
指定別名的通用語法如下:
from _module_name_ import _function_name_ as _fn_
1.10.4.使用as給模塊指定別名
你還可以給模塊指定別名的烁。通過給模塊指定剪短的別名(如給模塊pizza指定別名p)褐耳,讓你能夠更輕松地調(diào)用模塊中的函數(shù)。相比于pizza.make_pizza(),p.make_pizza()更為簡(jiǎn)潔渴庆。
import pizza as p
p.make_pizza(16,'pepperoni')
p.make_pizza(12,'mushrooms','green peppers','exrta cheese')
上述import語句給模塊pizza指定了別名p铃芦,但該模塊中所有函數(shù)的名稱都沒變。調(diào)用函數(shù)make_pizza()時(shí)襟雷,可編寫代碼p.make_pizza()而不是pizza.make_pizza()刃滓,這樣不僅能使代碼更簡(jiǎn)潔,還可以讓你不再關(guān)注模塊名耸弄,而專注于描述性的函數(shù)名咧虎。這些函數(shù)名明確地指出了函數(shù)的功能,對(duì)理解代碼而言计呈,它們比模塊名更重要砰诵。
給模塊指定別名的同于語法如下:
import _module_name as mn_
1.10.5.導(dǎo)入模塊中的所有函數(shù)
使用星號(hào)(*)運(yùn)算符可讓python導(dǎo)入模塊中的所有函數(shù):
from pizza import *
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green pippers','extra cheese')
import語句中的星號(hào)讓python將模塊pizza中的每個(gè)函數(shù)都復(fù)制到這個(gè)程序文件中征唬。由于導(dǎo)入了每個(gè)函數(shù),可通過名稱來調(diào)用每個(gè)函數(shù)茁彭,而無需使用句點(diǎn)表示法总寒。然而,使用并非自己編寫的大型模塊時(shí)理肺,最好不要采用這種導(dǎo)入方法摄闸。
最佳的做法是,要么只導(dǎo)入你需要你使用的函數(shù)妹萨,要么導(dǎo)入整個(gè)模塊并使用句點(diǎn)表示法年枕。這能讓代碼更清晰,更容易閱讀和理解眠副。這里之所以介紹這種導(dǎo)入方法画切,只是想讓你在閱讀別人編寫的代碼時(shí),如果遇到類似于下面的import語句囱怕,能夠理解它們:
from _module_name_ import *
1.11.函數(shù)文檔字符串
函數(shù)文檔字符串documentation string(docstring)是在函數(shù)開頭霍弹,用來解釋其接口的字符串。簡(jiǎn)而言之:
- 包含函數(shù)的基礎(chǔ)信息
- 包含函數(shù)的功能簡(jiǎn)介
- 包含每個(gè)形參的類型娃弓,使用等信息
- 必須在函數(shù)的首行典格,經(jīng)過驗(yàn)證前面有注釋性說明是可以的,不過最好函數(shù)文檔出現(xiàn)在首行
- 使用三引號(hào)注解的多行字符串(當(dāng)然台丛,也可以是一行)耍缴,因三引號(hào)可以實(shí)現(xiàn)多行注解(展示)(''' ''')或(""" """)
- 函數(shù)文檔的第一行一般概述函數(shù)的主要功能,第二行空挽霉,第三行詳細(xì)描述防嗡。
查看方式 - 在交互模式下可以使用help查看函數(shù),幫助文檔侠坎,該界面會(huì)調(diào)到幫助界面蚁趁,需要輸入q退出界面
- 使用doc屬性查看,該方法的幫助文檔文字直接顯示在交互界面上实胸。代碼如下:
def test(msg):
"""
函數(shù)名:test
功能:測(cè)試
參數(shù):無
返回值:無
:param msg:
:return:
"""
print("函數(shù)輸出成功" + msg)
test('hello')
print(help(test))
print(test.__doc__)
函數(shù)輸出成功hello
Help on function test in module __main__:
test(msg)
函數(shù)名:test
功能:測(cè)試
參數(shù):無
返回值:無
:param msg:
:return:
None
函數(shù)名:test
功能:測(cè)試
參數(shù):無
返回值:無
:param msg:
:return: