1. 程式人生 > 其它 >函式,形參與實參

函式,形參與實參

本章內容

  • 函式的定義與呼叫
  • 函式的分類
  • 函式的返回值
  • 函式的引數

函式的定義與呼叫

"""
函式的使用必須遵循’先定義,後呼叫’的原則。函式的定義就相當於事先將函式體程式碼儲存起來,然後將記憶體地址賦值給函式名,函式名就是對這段程式碼的引用,這和變數的定義是相似的。沒有事先定義函式而直接呼叫,就相當於在引用一個不存在的’變數名’。
"""
# 1. 函式一定要遵循先定義再呼叫的原則
# 2. 函式在定義階段只檢測語法不執行程式碼
# 3. 函式體程式碼只有在呼叫函式的時候才會執行
# 4. 函式名其實相當於是變數名指向的是記憶體中函式體程式碼所在的位置
eg :
    定義函式:
    def func():
        print('hello world')
    呼叫函式:
    func()   # hello world

函式的分類

1.內建函式
    python直譯器提前定義好可以直接呼叫的函式
    eg: len、open...  # 檢視程式碼的內部原始碼 >>>>> ctrl+左鍵
2.自定義函式
    1.1 自己編寫的函式
    2.1 無參函式
    2.3 空函式
# 1. 無參函式:在函式定義階段括號內沒有引數
# def index():
#    print('python是最牛逼的')
# 呼叫無參函式時括號內也不需要寫引數
# index()

# 2. 有參函式:在函式定義階段時括號內有引數>>>:類似於變數名
# def index(a):
#      print('python是最牛逼的',a)
# 呼叫有參函式:在函式呼叫階段括號內也必須傳引數>>>:類似於變數值
# index(666)

# 3.空函式:在定義階段函式體程式碼用pass或者...佔位
# def func():
#     pass
"""
定義空函式通常是有用的,因為在程式設計的開始,往往是先想好程式都需要完成什麼功能,然後把所有功能都列舉出來用pass充當函式體“佔位符”,這將使得程式的體系結構立見,清晰且可讀性強。
"""

函式的返回值

# 函式的返回值其實就是函式被呼叫後返回的結果
# 獲取函式的返回值
	變數名 = 函式呼叫
# 如何操作返回值
	1.當函式體程式碼沒有return關鍵字的時候,返回值是None
    eg:
    	def func():
    		print('你他喵的,哈哈哈!!!')
		s = func()
		print(s)
 2. 當函式體程式碼寫了return但是沒有跟任何值得時候 返回值也是None
    	def func():
    	     print('你他喵的,哈哈哈!!!')
             return
	s = func()
	print(s)
3.當函式體程式碼寫了return並且跟了資料 那麼寫什麼就返回什麼
  	如果寫的是值那麼直接返回值(任意資料型別)
    如果寫的是變數名那麼返回變數名指向的值
eg:
    def func():
    	name = 'jerry'
    	return name
	s = func()
	print(s)		
4.return後面還可以跟多個值 逗號隔開  會自動組織成元組返回出去後
eg:
    def func():
    	print('python是最牛逼的語言')
    	name = 'jerry'
    	name2 = 'kevin'
    	return name,name2,18,19
	s = func()
	print(s)
5.函式體程式碼遇到return會立刻結束函式執行
  函式體程式碼裡面寫return相當於迴圈體程式碼裡面寫break
  遇到了就立刻結束函式和迴圈的執行

函式的引數

1.函式的引數可以分為兩大類
    1.函式在定義階段括號內寫的引數
    	我們稱之為'形式引數',簡稱為>>>>>:形參
    2.函式在呼叫階段括號內寫的引數
    	我們稱之為'實際引數',簡稱為>>>>>:實參
2.形參與實參的關係
    形參類似於是變數名、實參類似於是變數的值
    在呼叫函式的時候傳入實參 會與形參臨時繫結
    函式執行結束之後自動結束繫結
	eg:
        def func(a,b):
    	    print(a,b)
            return 0
        func('jason',18)    

位置引數

位置形參:
    在函式的定義中,括號內依次從左往右寫上變數名
    def func(name,age,gender):   # 這裡的name,age,gender就是位置形參
    	print(f'他叫{name},{age}歲了,性別是{gender}')
    	return 666
位置實參:
    func('jason',18,'male')     # 這裡的jaosn,18,male就是位置實參
    
位置引數的特徵:
	1.位置形參與位置實參在繫結關係的時候就是按照從左往右的順序依次繫結
    2.位置形參與位置實參的個數要一致 # 多一個不行少一個也不行
    
    eg:
        func('jason',18,'male')   # 正確
	func()                    # 報錯
	func('jason',18)          # 報錯
	func('jason',19,'male',182)  # 報錯

關鍵字引數

出現在實參中
	指名道姓的給形參傳值 不需要遵循位置
    def func(name,age,gender):   
    	print(f'他叫{name},{age}歲了,性別是{gender}')
    	return 666
    func(name = 'jason',age = 18,gender = 'male')    # 關鍵字引數
    func('tony',name='jason',gender='male')        # 報錯 形參只能指向一個實參
	func(name='jerry',age=18,'male')     # 報錯 位置引數必須在關鍵字引數前面
	func('jason',19,gender='male')      # 正確

預設引數

出現在形參中
	在函式定義階段就已經給一些形參賦值了 
  	後續如果不傳值則使用預設的
        後續如果傳值則使用傳入的
	預設引數的出現也打破了形參與實參之間個數一致的情況
  預設引數必須定義在位置引數的後面  # 至於順序問題 後面有口訣
eg:
    def func(name,age,gender='male'):
   	print(f'他叫{name},{age}歲了,性別是{gender}')
    	return 666
    func('jason',19,)
    func(name='tony',age=20)
    func('jerry',20,'remale')

可變長引數(重要)

需求:定義一個函式,無論傳多少位置實參都可以正常執行
	類似於print
    def func(*a):
    	print(a)
    func()                         # ()
    func(1)                        # (1,)
    func(1,2)                      # (1, 2)
    func(1,2,3,4,5,6,6)            # (1, 2, 3, 4, 5, 6, 6)
    
# *號在形參中
    #可以接收多餘的位置引數 並組織成元組的形式賦值給*號後面的變數名
    eg:
         def func(a, b, *s):
    	      print(a, b, s)
         func(1)                    # 報錯,至少要傳兩個引數a和b
	 func(1,2)                  # 1 2 ()
	 func(1,2,3)                # 1 2 (3,)
	 func(1,2,3,4)              # 1 2 (3, 4)
        
        
# **在形參中
    # 用於接收多餘的關鍵字引數 並且組織成字典的形式賦值給**後面的變數名
    eg:
        def index(a, b, **k):
    	    print(a, b, k)
	index(a=1, b=2)  # 1 2 {}
	index(a=1, b=2, c=3, name='jason')  # 1 2 {'c': 3, 'name': 'jason'}
	index(1,2,name='jason',age=18,pwd=123)  # 1 2 {'name': 'jason', 'age': 18, 'pwd': 123}
'''需求:定義一個函式 無論傳入多少關鍵字引數都可以正常執行'''
		def func(**k):
    		    print(k)
		func()  # {}
		func(a=1,b=2)  # {'a': 1, 'b': 2}
		func(a=1,b=2,c=3,d=4)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

可變長形參

"""
思考題:如何定義一個無論接收多少個任意型別的引數都可以正常執行的函式
"""
    def func(*a,**k):
        print(a,k)
    func()  # () {}
    func(1,2,3,4,name='jason',age=18)  # (1, 2, 3, 4) {'name': 'jason', 'age': 18}
    
# 以後在定義函式的時候 如果不確定這個函式將來需要多個實參 那麼可以採用上述的方法

"""*和**在形參中的使用 後面的變數名並不是關鍵 但是針對這兩個特殊符號後面的變數名 有推薦的寫法"""

    def index(*args, **kwargs):
        pass

補充說明

*和**不單單可以在形參中使用 還可以在實參中使用
def index(*args, **kwargs):
    print(args, kwargs)
 
"""
 *號在實參中 
    可以將列表或者元組打散成位置引數一一傳入
"""   
def func(*args, **kwargs):
    print(args, kwargs)
func(*[1, 2, 3, 4, 5, 6])          # (1, 2, 3, 4, 5, 6) {}
func(*(1, 2, 3, 4, 5, 6))          # (1, 2, 3, 4, 5, 6) {}
func([1, 2, 3, 4, 5, 6])           # ([1, 2, 3, 4, 5, 6],) {}

"""
**號在實參中
    可以將字典打散成關鍵字引數一一傳入
"""
def func(*args, **kwargs):
    print(args, kwargs)
func(**{'name': 'jason', 'name2': 'tony', 'name3': 'jerry'})
# () {'name': 'jason', 'name2': 'tony', 'name3': 'jerry'}
func({'name': 'jason', 'name2': 'tony', 'name3': 'jerry'})
# ({'name': 'jason', 'name2': 'tony', 'name3': 'jerry'},) {}