day10學習筆記之函式上

weixin_45389821發表於2020-11-14

函式的介紹

  • 函式也是個物件 function

  • 函式可以用來儲存一些可執行的程式碼,並且可以在需要的時候,多次對這些程式碼呼叫.

  • 語法
    def 函式名(形參1,形參2…):
    程式碼塊
    return [‘返回值1’,‘返回值2’…]
    呼叫函式
    函式物件(實參1,實參2…)

def fn():
	print('Hello World!')
fn()

注意:fn是函式物件 fn() 呼叫函式。

函式的引數

形參和實參

  • 在定義函式的時候,可以在函式名後面的括號中定義數量不等的形參,定義多個形參要用","隔開.
  • 形參(形式引數) 定義形參就是相當於在函式內部宣告瞭變數,不是賦值
  • 實參(實際引數) 如果函式定義的時候指定了形參,那麼在呼叫的時候也必須傳遞實參.實參將會賦值給對應的形參,簡單來說,有幾個形參就得幾個實參。
#定義兩個數相加
def addition(a,b):
	print(a,'+',b,'=',a+b)
addition(111,222)
# 111 + 222 = 333

函式的傳遞方式

定義形參時,可以為形參指定預設值。指定了預設值以後,如果⽤戶傳遞了引數則預設值不會⽣效。如果⽤戶沒有傳遞,則預設值就會⽣效。

def fn(a=10):
	print('a=',a)
fn()
fn(20)
  • 位置引數:位置引數就是將對應位置的實參賦值給對應位置的形參。
def fn(a,b,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)

fn(1,2,3)
  • 關鍵字引數 :關鍵字引數可以不按照形參定義的順序去傳遞,⽽根據引數名進⾏傳遞。
def fn(a,b,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)

fn(b=1,c=2,a=3)

混合使⽤位置引數和關鍵字引數的時候必須將位置引數寫在關鍵字引數前⾯

def fn(b,c,a):
    print('a=',a)
    print('b=',b)
    print('c=',c)

fn(13,a=12,c=45)
#錯誤示例:
def fn(a,b,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)
fn(13,a=12,c=45)
fn(a=13,b,c=45)
'''
fn(13,a=12,c=45)
TypeError: fn() got multiple values for argument 'a'

fn(a=13,12,c=45)
            ^
SyntaxError: positional argument follows keyword argument
'''

實參的型別

  • 實參可以傳遞任意型別的物件。
def fn(a):
    print('a=',a)
fn(123)
fn(True)
fn('111')
fn([1,2,3,4])
fn((1,2,3,4))
fn({'name':'亞瑟'})
  • 函式內進行運算時,需要注意引數的型別,在程式中不同型別的引數不能進行運算。
def fn(a,b):
    '''定義兩個函式相加'''
    print(a+b)
fn(1,'2')
'''
print(a+b)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
'''

擴充

在函式中重新給形參賦值,不會影響其他的變數,如果現在的形參執行的是一個物件,當我們通過形參去修改物件時,會影響到所有指向該物件的變數。

def fn(a):
	print('a=',a,id(a))
c = 10
print('呼叫函式前c=',c,id(c))
fn(c)
print('呼叫函式後c=',c,id(c))
# 呼叫函式前c= 10 140713040615360
# a= 10 140713040615360
# 呼叫函式後c= 10 140713040615360

相當於 a=c 將變數c賦值給a,a,c通過指向記憶體中的同一物件。

def fn(a):
	a = 20 #重新給形參賦值
	print('a=',a,id(a))
c = 10
print('呼叫函式前c=',c,id(c))
fn(c)
print('呼叫函式後c=',c,id(c))

#呼叫函式前c= 10 140713040615360
# a= 20 140713040615680
#呼叫函式後c= 10 140713040615360

這相當於兩個過程,首先將變數c賦值給a,然後再將變數a重新賦值.

#實參是一個列表,
def fn(a):
	a[0]=10  #修改物件
	print('a=',a,id(a))
c = [1,2,3]
print('呼叫函式前c=',c,id(c))
fn(c)
print('呼叫函式後c=',c,id(c))
# 呼叫函式前c= [1, 2, 3] 1618098450048
# a= [10, 2, 3] 1618098450048
# 呼叫函式後c= [10, 2, 3] 1618098450048

對於不明白的可參考文章中的可變物件

不定長引數

通常我們所見不定長引數有兩種,一種是在形參前加‘*’號,另外一種是在形參前加‘**’號。

  • 定義函式時,可以在形參前⾯加⼀個*,這樣這個形參可以獲取到所有的實參,它會將所有的實參儲存到⼀個元組中。
def fn(*args):
    '''定義一個任意個數的數字相加的函式'''
    r = 0 ##定義變數儲存結果
    for i in args: #遍歷元組
        r+=i  # r = r + i
    print(r)
fn(1,2,3,4,5,6,7,8,9)

#45
def fn(*args):
    '''將任意個列表合併成一個列表的函式'''
    r = [] #定義變數儲存結果
    for i in args: #遍歷元組
        r+=i   # r = r + i
    print(r)
fn([1,2,3],[4,5,6],[7,8,9])

#[1, 2, 3, 4, 5, 6, 7, 8, 9]
#應用1 位置引數和帶一個*號不定長引數的應用
def choice(shunt,*heros):
    print('你選擇了'+shunt)
    print(shunt+'有以下英雄:')
    for i in heros:
        print('-->',i)

choice('中路','安琪拉','妲己','諸葛亮','周瑜','上官婉兒')

在這裡插入圖片描述

  • 帶兩個* 號的形參可以接收關鍵字引數,它會將這些統⼀儲存到字典當中。字典的鍵(key)就是引數的名字,字典的值(value)就是引數的值。
def fn(**a):
	print('a=',a)
fn(a=1,b=2,c=3,d=4)
a= {'a': 1, 'b': 2, 'c': 3, 'd': 4}

def fn(name,price,**kwargs):
    s = {} #建立一個空字典來儲存資料
    s['name'] = name
    s['price'] = price
    for k,v in kwargs.items():
        s[k] = v
    print(s)

fn('亞瑟',450,passive_skill='聖光守護',frist_skill='誓約之盾',second_skill='迴旋打擊',space='聖劍制裁')

#{'name': '亞瑟', 'price': 450, 'passive_skill': '聖光守護', 'frist_skill': '誓約之盾', 'second_skill': '迴旋打擊', 'space': '聖劍制裁'}

注意事項:
1.在形參中只能有一個帶號 * 的引數,帶一個 * 號的形參只能接受位置引數,不能接受關鍵字引數。
2.不定長引數不一定非要寫在後面,但是要注意,帶 * 號後面的引數,都必須以關鍵字引數的形式來進行傳遞。
3. 帶兩個 * 號的形參只有⼀個,並且必須寫在所有引數的後面。

函式的返回值

  • 函式的返回值就是函式執行以後返回的結果,一般都是通過return來指定函式的返回結果。
'''
函式的語法:
def 函式名(形參1,形參2,....):
	程式碼塊
	return 返回值
函式名(實參1,實參2,...)
'''
  • 可以直接使用函式的返回值,也可以通過一個變數來接收函式的返回值。
def fn():
	pass  #沒有執行的程式
	return 'Hello World!'  #指定返回值
r = fn()
print(r)
# Hello World!
  • 在函式中,return沒有指定返回值,或者沒有return,則相當於return None.另外在return後面的程式碼都不會執行,函式中的return相當於結束此函式執行的指令。
def s(*arg):
	r = 0 #定義變數儲存資料
	for i in arg:
		if i == 4:
			return r
		else:
			r+=i
a=s(1,2,3,4,5,6)
print('a=',a)
#6

函式的作用域

作用域是什麼?作用域就是變數生效的區域。
作用域為分為全域性變數和區域性變數。

區域性變數

  • 某個變數只有在該函式內使用,影響範圍限定在這個函式內,這個變數稱為區域性變數。
  • 在函式呼叫時建立,在呼叫結束時銷燬。
def info():
	msg = '我是區域性變數'
	print(msg)
info()

全域性變數

  • 某個變數的影響範圍是在整個程式,這個變數成為全域性變數。
  • 在程式執行時建立,在程式執行結束時銷燬。
def info():
	print(msg)
msg = '我是全域性變數'
info()

注意事項:

  • 區域性變數內容無法在其他函式引用,若要引用,則需要轉化為全域性變數。方法:在程式頭加一行 global 變數名.
  • 區域性變數內容無法在主程式呼叫。
def info():
    global msg  #將區域性變數轉換為全域性變數
    msg = '區域性變數'
    print(msg)
msg = '全部變數'
info()
print(msg)

文件字串

文件字串在程式內用三引號’’‘內容’’'表示.通過用來說明這個函式的作用,引數的說明,返回值,讓人很容易使用和理解這函式。檢視方法help(函式名)。

def fn(a:int=1,b:float=1.0,c:str='Hello'):
    '''
    這是一個文件字串的例項
    :param a:  作用 型別 預設值 說明
    :param b: 作用 型別 預設值 說明
    :param c: 作用 型別 預設值 說明
    :return:  返回值是多少
    '''
    return 0
help(fn)

遞迴函式

  • 遞迴是什麼?遞迴是一種解決問題的思想 ,整體思想是將一個大問題分解為一個一個的小問題,直到問題無法分解時,再去解決問題。
  • 遞迴式的函式需要2個條件:
    • 基線條件:問題可以被分解成最小問題,當滿足基線條件時,遞迴就不在執行了。
    • 遞迴條件:問題可以繼續被分解。

求10的階乘的方法。

'''
思路:
1! = 1
2! = 2 * 1
3! = 3 * 2 * 1
10 ! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 
'''
方法一:
s = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 
方法二:
n = 1
for i in range(10,1,-1):
	 n *=i
print(n)
#或者
n=1
for i in range(0,10):
	n*=i
print(n)

使用遞迴的方法求10的階乘

def fn(n):
	if n ==1:
		return 1
	else:
		return n*fn(n-1)

s=fn(10)
print(s)

小練習

定義一個函式,用來檢查一個任意的字串是否是迴文字串,如果是返回True,不是返回False。回 文字串從前往後念和從後往前念是一樣的。例如 TNT。
思路:根據輸入的字串判斷從前往後念和從後往前念是一樣的,即n[i]==[-i-1]。

#不使用遞迴方法
def fn(n:str):
    ''' 這個函式用於判斷輸入字串是否是迴文字串
    :param n: 引數 字串 
    :return: True or False
    '''
    for i in range(len(n)): 
        if n[i] == n[-i-1]: #判斷條件
            continue  #繼續下一次判斷
        else:
            return False #不滿足就退出函式,並返回False
    return True  #條件都滿足後,退出函式返回True



if __name__=='__main__':  #主函式
    n = str(input('輸入一個需要判斷的字串:')) #輸入字串
    if n != '':   #輸入不能為空,空無法判斷
        s = fn(n) #呼叫函式
        print(s)  #顯示結果
    else:
        print('輸入有誤')

#使用遞迴方法:

def fn(n):
    num = len(n)
    if num == 0:
        return True
    elif num == 1:
        return True
    else:
        if n[0] == n[-1]:
            n.pop()   #刪除列表最後一位
            n.reverse() #顛倒列表
            n.pop() #刪除列表最後一位
            return fn(n)
        else:
            return False

if __name__=='__main__':  #主函式
    n = list(str(input('輸入一個需要判斷的字串:'))) #輸入字串
    if n :   #輸入不能為空,空無法判斷
        s=fn(n) #呼叫函式
        print(s)  #顯示結果
    else:
        print('輸入有誤')

相關文章