python_函數(shù)

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:
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末他嫡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子庐完,更是在濱河造成了極大的恐慌钢属,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件门躯,死亡現(xiàn)場(chǎng)離奇詭異淆党,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門宁否,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窒升,“玉大人,你說我怎么就攤上這事慕匠”バ耄” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵台谊,是天一觀的道長(zhǎng)蓉媳。 經(jīng)常有香客問我,道長(zhǎng)锅铅,這世上最難降的妖魔是什么酪呻? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮盐须,結(jié)果婚禮上玩荠,老公的妹妹穿的比我還像新娘。我一直安慰自己贼邓,他們只是感情好阶冈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著塑径,像睡著了一般女坑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上统舀,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天匆骗,我揣著相機(jī)與錄音,去河邊找鬼誉简。 笑死碉就,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闷串。 我是一名探鬼主播铝噩,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼窿克!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毛甲,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤年叮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后玻募,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體只损,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跃惫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叮叹。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖爆存,靈堂內(nèi)的尸體忽然破棺而出蛉顽,到底是詐尸還是另有隱情,我是刑警寧澤先较,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布携冤,位于F島的核電站,受9級(jí)特大地震影響闲勺,放射性物質(zhì)發(fā)生泄漏曾棕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一菜循、第九天 我趴在偏房一處隱蔽的房頂上張望翘地。 院中可真熱鬧,春花似錦癌幕、人聲如沸衙耕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臭杰。三九已至,卻和暖如春谚中,著一層夾襖步出監(jiān)牢的瞬間渴杆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工宪塔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留磁奖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓某筐,卻偏偏與公主長(zhǎng)得像比搭,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子南誊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355