1.1.函數(shù)定義
1.1.1.定義一個函數(shù)
1.1python定義函數(shù)用def關(guān)鍵字,一般格式如下
def 函數(shù)名(參數(shù)列表):
函數(shù)體
1.2函數(shù)名的命名規(guī)則
形參:形式參數(shù),不是實(shí)際存在,是虛擬變量。在定義函數(shù)和函數(shù)體的時候使用形參,目的是在函數(shù)調(diào)用時接收實(shí)參(實(shí)參個數(shù),類型與實(shí)參一一對應(yīng))
實(shí)參:實(shí)際參數(shù),調(diào)用函數(shù)時傳給函數(shù)的參數(shù),可以是常量,變量,表達(dá)式,函數(shù),傳給形參
區(qū)別:形參是虛擬的,不占用內(nèi)存空間,形參變量只有在被調(diào)用時才分配內(nèi)存單元,實(shí)參是一個變量,占用內(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ù)
- 不定長參數(shù)
1.2.1.必需參數(shù):
必需參數(shù)須以正確的順序傳入函數(shù)。調(diào)用時的數(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ù)的順序與聲明時不一致,因?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ù)的值如果沒有傳入,則被認(rèn)為是默認(rèn)值。下例會打印默認(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.不定長參數(shù)
你可能需要一個函數(shù)能處理比當(dāng)初聲明時更多的參數(shù)。這些參數(shù)叫做不定長參數(shù),和上述2眾參數(shù)不同,聲明時不會命名。
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
加了星號的變量名會存放所有未命名的變量參數(shù),而加兩個星號的變量名會存放命名的變量參數(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í)行代碼,會把函數(shù)調(diào)用看做是一行代碼直接執(zhí)行
- F7 Step Into 可以單步執(zhí)行代碼,如果是函數(shù),會進(jìn)入函數(shù)內(nèi)部
1.3.函數(shù)的返回值
要想獲得函數(shù)的執(zhí)行結(jié)果,就可以用return語句把結(jié)果返回
注意:
函數(shù)在執(zhí)行過程中只要遇到return語句,就會停止執(zhí)行并返回結(jié)果,所以也可理解為return語句代表著函數(shù)的結(jié)束,如果未在函數(shù)中指定return,那這個函數(shù)的返回值為None
return多個對象,解釋器會把這多個對象組裝成一個元組作為一個一個整體結(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ù)返回的多個值,多個返回值被封裝成元組
tp = sum_and_avg(my_list)
print(tp)
20 20.0
1.4.高階函數(shù)
高階函數(shù)是至少滿足下列一個條件的函數(shù):
接受一個或多個函數(shù)作為輸入 輸出一個函數(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,嵌套的父級函數(shù)的局部作用域,即包含此函數(shù)的上級函數(shù)的局部作用域,但不是全局的;
G:global,全局變量,就是模塊級別定義的變量;
B:builtin,系統(tǒng)固定模塊里面的變量,比如int,bytearray等。
搜索變量的優(yōu)先級順序依次是:作用域局部>外層作用域>當(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是相對的,enclosing
變量相對上層來說也是local。
1.5.2.作用域產(chǎn)生
在python中,只有模塊(module),類(class)以及函數(shù)(def,lambda)才會引入新的作用域,其他的代碼塊(如if、try、for等)是不會引入新的作用域的,如下代碼:
if 2 > 1:
x = 1
print(x)
1
這個是沒有問題的,if并沒有引入一個新的作用域,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()
#錯誤的原因在于print(x)時,解釋器會在局部作用域找,會找到x=5(函數(shù)已經(jīng)加載到內(nèi)存),但x使用在聲明前了,所以報(bào)錯;
#local varible 'x' referenced before assignment.如何證明找到了x=5呢?簡單:注釋掉x=5,x=6
#報(bào)錯為:name 'x' is not defined
#同理
x = 6
def f2():
x += 1
f2()
報(bào)錯為:UnboundLocalError: local variable 'x' referenced before assignment
1.5.4.global關(guān)鍵字
當(dāng)內(nèi)部作用域想修改外部作用域的變量時,就要用到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作用域,外層非全局作用域)中的變量怎么辦呢,這時就需要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)對于一個變量,內(nèi)部作用域先聲明就會覆蓋外部變量,不聲明直接使用,就會使用外部作用域的變量;
(4)內(nèi)部作用域要修改外部作用域變量的值時,全局變量要使用global關(guān)鍵字,嵌套作用域變量要使用nonlocal關(guān)鍵字。nonlocal是python3新增的關(guān)鍵字,有了這個關(guān)鍵字,就能完美地實(shí)現(xiàn)閉包了。
1.6.遞歸函數(shù)
定義:在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)。如果一個函數(shù)在內(nèi)部調(diào)用自身本身,這個函數(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):是定義簡單,邏輯清晰。理論上,所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)的邏輯不如遞歸清晰。
1.6.3.遞歸特性:
1.必須有一個明確的結(jié)束條件
2.每次進(jìn)入更深一層遞歸時,問題規(guī)模相比上次遞歸都應(yīng)有所減少
3.遞歸效率不高,遞歸層次過多會導(dǎo)致棧溢出(在計(jì)算機(jī)中,函數(shù)調(diào)用是通過棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,每當(dāng)進(jìn)入一個函數(shù)調(diào)用,棧就會加一層棧幀,每當(dāng)函數(shù)返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調(diào)用的次數(shù)過多,會導(dǎo)致棧溢出)
1.7.匿名函數(shù)
匿名函數(shù)就是不需要顯式的指定函數(shù)名。

關(guān)鍵字lambda表示匿名函數(shù),冒號前面的n表示函數(shù)參數(shù),可以有多個參數(shù)。
匿名函數(shù)有個限制,就是只能有一個表達(dá)式,不用寫return,返回值就是該表達(dá)式的結(jié)果。
用匿名函數(shù)有個好處,因?yàn)楹瘮?shù)沒有名字,不必?fù)?dān)心函數(shù)名沖突。此外,匿名函數(shù)也是一個函數(shù)對象,也可以把匿名函數(shù)賦值給一個變量,再利用變量來調(diào)用該函數(shù)。
有些函數(shù)在代碼中只用一次,而且函數(shù)體比較簡單,使用匿名函數(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ù)接收兩個參數(shù),一個是函數(shù),一個是Iterable,map將傳入的函數(shù)依次作用到序列的每個元素,并把結(jié)果作為新的Iterator返回
遍歷序列,對序列中每個元素進(jìn)行函數(shù)操作,最終獲取新的序列。

求列表[1,2,3,4,5,6,7,8,9],返回一個n*n的列表
#一般解決方案
li = [1,2,3,4,5,6,7,8,9]
for ind,val in enumerate(li):
li[ind] = val * val
print(li)
#高級解決方案
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把一個函數(shù)作用在一個序列[x1,x2,x3,...]上,這個函數(shù)必須接收兩個參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個元素做累積運(yùn)算,其效果就是:
reduce(func,[1,2,3])等同于func(func(1,2),3)
對于序列內(nèi)所有元素進(jìn)行累計(jì)操作


#接受一個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()也接收一個函數(shù)和一個序列。和map()不同的是,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
對于序列中的元素進(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.請利用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)
接收一個key函數(shù)來實(shí)現(xiàn)對可迭代對象進(jìn)行對象進(jìn)行自定義的排序
可迭代對象:主要與列表,字符串,元組,集合和字典
key:接收一個函數(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]))
"""
對字符串排序,是按照ASCII的大小比較的,由于‘Z’<‘a(chǎn)',結(jié)果,大寫字母z會排在小寫字母a的前面。
"""
['Credit', 'Zoo', 'about', 'bad']
L = [('Bob',75),('Adam',92),('Bart',66),('Lisa',88)]
#調(diào)用sorted()對上述列表分別按名字排序
print(sorted(L,key=lambda x:x[0]))
#再按成績從高到低排序
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é)會了上面幾個重要的函數(shù)過后,我們就可以來聊一聊函數(shù)式編程了。
--概念(函數(shù)式編程)函數(shù)式編程是一種編程范式,我們常見的編程范式有命令式編程,函數(shù)式編程,常見的面向?qū)ο缶幊桃彩且环N命令式編程。
命令式編程是面向計(jì)算機(jī)硬件的抽象,有變量(對應(yīng)著存儲單元),賦值語句(獲取,存儲指令),表達(dá)式(內(nèi)存引用和算術(shù)運(yùn)算)和控制語句(跳轉(zhuǎn)指令),一句話,命令式程序就是一個馮諾依曼機(jī)的指令序列。
而函數(shù)式編程是面向數(shù)學(xué)的抽象,將計(jì)算機(jī)描述為一種表達(dá)式求值,一句話,函數(shù)式編程就是一個表達(dá)式。
函數(shù)式編程的本質(zhì)
函數(shù)式編程中的函數(shù)這個術(shù)語不是指計(jì)算機(jī)中的函數(shù),而是指數(shù)學(xué)中的函數(shù),即自變量的映射。也就是說一個函數(shù)的值僅決定于函數(shù)參數(shù)的值,不依賴其他狀態(tài)。比如y=x*x函數(shù)計(jì)算x的平方,只要x的平方,不論什么時候調(diào)用,調(diào)用幾次,值都是不變的。
純函數(shù)式編程語言中的變量也不是命令式編程語言中的變量,即存儲狀態(tài)的單元,而是代數(shù)中的變量,即一個值的名稱。變量的值時不可變的,也就是說不允許像命令式編程語言中那樣多次給一個變量賦值。比如說在命令式編程語言我們寫“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ù),并對大于0的數(shù)進(jìn)行累加,最后求取平均值。
這就是命令式編程--你要做什么事情,你得把達(dá)到目的的步驟詳細(xì)的描述出來,然后交給機(jī)器去運(yùn)行。
這也正是命令式編程的理論模型--圖靈機(jī)的特點(diǎn)。一條寫滿數(shù)據(jù)的紙帶,一條根據(jù)紙帶內(nèi)容運(yùn)動的機(jī)器,機(jī)器每動一步都需要紙帶上寫著如何達(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ù)存儲在模塊中
函數(shù)的優(yōu)點(diǎn)之一是,使用它們可將代碼塊與主程序分離。通過給函數(shù)指定描述性名稱,可讓主程序容易理解得多。你還可以更近一步,講函數(shù)存儲在被稱為模塊的獨(dú)立文件中,再將模塊導(dǎo)入到主程序中。import語句允許在當(dāng)前運(yùn)行的程序文件中使用模塊中的代碼。
通過將函數(shù)存儲在獨(dú)立的文件中,可隱藏程序代碼的細(xì)節(jié),將重點(diǎn)放在程序的高層邏輯上。這還能讓你在與眾不同的程序中重用函數(shù)。將函數(shù)存儲在獨(dú)立文件中,可與其他程序員共享這些文件而不是整個程序。知道如何導(dǎo)入函數(shù)還能讓你使用其他程序員編寫的函數(shù)庫。
導(dǎo)入模塊的方法有多種,下面對每種都作簡要的介紹。
1.10.1.導(dǎo)入整個模塊
要讓函數(shù)是可導(dǎo)入的,得先創(chuàng)建模塊。模塊是擴(kuò)展名為.py的文件,包含要導(dǎo)入到程序中的代碼。下面來創(chuàng)建一個包含函數(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)
接下來,我們在pizza.py所在的目錄中創(chuàng)建另一個名為making_pizzas.py的文件,這個文件導(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讀取這個文件時,代碼行import pizza讓python打開文件pizza.py,并將其中的所有函數(shù)都復(fù)制到這個程序中。你看不到復(fù)制的代碼,因?yàn)檫@個程序運(yùn)行時,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的整個模塊,就可使用下面的語法來使用其任何一個函數(shù):
_module_name.function_name_()
1.10.2.導(dǎo)入特定的函數(shù)
你還可以導(dǎo)入模塊中的特定函數(shù),這種導(dǎo)入方法的語法如下:
from _module_name_ import _function_name_
通過用逗號分隔函數(shù)名,可根據(jù)需要從模塊中導(dǎo)入任意數(shù)量的函數(shù):
from _module_name_ import _function_0,function_1,function_2_
對于前面的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ù)時就無需使用句點(diǎn)。由于我們在import語句中顯式地導(dǎo)入函數(shù)make_pizza(),因此調(diào)用它時只需指定其名稱。
1.10.3.使用as給函數(shù)指定別名
如果要導(dǎo)入的函數(shù)的名稱可能與程序中現(xiàn)有的名稱沖突,或者函數(shù)的名稱太長,可指定簡短而獨(dú)一無二的別名--函數(shù)的另一個名稱,類似于外號。要給函數(shù)指定這種特殊外號,需要在導(dǎo)入它時這樣做。
下面給函數(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();在這個程序中,每當(dāng)需要調(diào)用make_pizza()時,都可簡寫成mp(),而python將運(yùn)行make_pizza()中的代碼,這可避免與這個程序可能包含的函數(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()更為簡潔。
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()時,可編寫代碼p.make_pizza()而不是pizza.make_pizza(),這樣不僅能使代碼更簡潔,還可以讓你不再關(guān)注模塊名,而專注于描述性的函數(shù)名。這些函數(shù)名明確地指出了函數(shù)的功能,對理解代碼而言,它們比模塊名更重要。
給模塊指定別名的同于語法如下:
import _module_name as mn_
1.10.5.導(dǎo)入模塊中的所有函數(shù)
使用星號(*)運(yùn)算符可讓python導(dǎo)入模塊中的所有函數(shù):
from pizza import *
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green pippers','extra cheese')
import語句中的星號讓python將模塊pizza中的每個函數(shù)都復(fù)制到這個程序文件中。由于導(dǎo)入了每個函數(shù),可通過名稱來調(diào)用每個函數(shù),而無需使用句點(diǎn)表示法。然而,使用并非自己編寫的大型模塊時,最好不要采用這種導(dǎo)入方法。
最佳的做法是,要么只導(dǎo)入你需要你使用的函數(shù),要么導(dǎo)入整個模塊并使用句點(diǎn)表示法。這能讓代碼更清晰,更容易閱讀和理解。這里之所以介紹這種導(dǎo)入方法,只是想讓你在閱讀別人編寫的代碼時,如果遇到類似于下面的import語句,能夠理解它們:
from _module_name_ import *
1.11.函數(shù)文檔字符串
函數(shù)文檔字符串documentation string(docstring)是在函數(shù)開頭,用來解釋其接口的字符串。簡而言之:
- 包含函數(shù)的基礎(chǔ)信息
- 包含函數(shù)的功能簡介
- 包含每個形參的類型,使用等信息
- 必須在函數(shù)的首行,經(jīng)過驗(yàn)證前面有注釋性說明是可以的,不過最好函數(shù)文檔出現(xiàn)在首行
- 使用三引號注解的多行字符串(當(dāng)然,也可以是一行),因三引號可以實(shí)現(xiàn)多行注解(展示)(''' ''')或(""" """)
- 函數(shù)文檔的第一行一般概述函數(shù)的主要功能,第二行空,第三行詳細(xì)描述。
查看方式 - 在交互模式下可以使用help查看函數(shù),幫助文檔,該界面會調(diào)到幫助界面,需要輸入q退出界面
- 使用doc屬性查看,該方法的幫助文檔文字直接顯示在交互界面上。代碼如下:
def test(msg):
"""
函數(shù)名:test
功能:測試
參數(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
功能:測試
參數(shù):無
返回值:無
:param msg:
:return:
None
函數(shù)名:test
功能:測試
參數(shù):無
返回值:無
:param msg:
:return: