【python】-- 函數、無參/有參參數、全局變量/局部變量


函數

函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。

函數能提高應用的模塊性,和代碼的重復利用率。你已經知道Python提供了許多內建函數,比如print()。但你也可以自己創建函數,這被叫做用戶自定義函數。

 

一、定義函數

1、定義一個由自己想要功能的函數,以下是簡單的規則:

  • 函數代碼塊以 def 關鍵詞開頭,后接函數標識符名稱和圓括號 ()。
  • 任何傳入參數和自變量必須放在圓括號中間,圓括號之間可以用於定義參數。
  • 函數的第一行語句可以選擇性地使用文檔字符串—用於存放函數說明。
  • 函數內容以冒號起始,並且縮進。
  • return [表達式] 結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None。
def test():
    """
      for test
    """
    print("in the test funcation")
    return 0

# def  定義函數的關鍵字
# test 函數名(函數標識名稱符)
# ()  任何傳入參數和自變量必須放在圓括號中間,圓括號之間可以用於定義參數
#  """for test"""  函數說明,說明函數作用,方便他人閱讀代碼
# print("in the test funcation") 函數體(代碼塊),注意縮進
#  return 結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None

2、函數特征:

  • 代碼重復利用
  • 可擴展性
  • 保持一致性

優化前:

#打印字符串
print("ABCD")
print("EFGH")
 
#現在下面有2個函數,每個函數處理完了,都需要使用上面的邏輯,那么唯一的方法就是拷貝2次這樣的邏輯

def test_1():
    "test"
    print("in the test1")
    print("ABCD")
    print("EFGH")
    

def test_2():
    "test"
    print("in the test2")
    print("ABCD")
    print("EFGH")
View Code

優化后:

# 新定義一個函數
def test():
    """test"""
    print("ABCD")
    print("EFGH")

#在想執行打印字符串功能的函數中,調用test()函數就可以了
def test_1():
    """test"""
    print("in the test1")
    test()# 調用test()函數
 
def test_2():
    """test"""
    print("in the test2")
    test()# 調用test()函數
View Code

 

二、有參函數和無參函數:

1、無參函數實現和調用:

# 定位test() 無參函數
def test():
    print("in the test")


test() #調用函數

# in the test
View Code

 

2、有參函數實現和調用:

下面說說帶參數的函數:

  • 形參:指的是形式參數,是虛擬的,不占用內存空間,形參單元只有被調用的時才分配內存單元
  • 實參:指的是實際參數,是一個變量,占用內存空間,數據傳遞單向,實參傳給形參,形參不能傳給實參

 

def test(x,y): #x,y是形參
    print(x)
    print(y)
 
test(1,2) #1和2是實參
#輸出
1
2

 

 

(1)、位置參數

從上面的例子可以看出,實際參數和形式參數是一一對應的,如果調換位置,x和y被調用的時,位置也會互換,代碼如下:
def test(x,y):
    print(x)
    print(y)
print("--------互換前-----")
test(1,2)
print("--------互換后-----")
test(2,1)
 
#輸出
--------互換前-----
1
2
--------互換后-----
2
1

 

 

 
因為定義x,y兩個形參,所以傳遞實參的時候,也只能傳遞兩個實參,多一個或少一個都是有問題的:

a:多傳遞一個參數

def test(x,y):
    print(x)
    print(y)
print("--------多一個參數----")
test(1,2,3)
 
#輸出
--------多一個參數----
Traceback (most recent call last):
  File "D:/PycharmProjects/pyhomework/day3/函數_帶參數.py", line 8, in <module>
    test(1,2,3)
TypeError: test() takes 2 positional arguments but 3 were given  #test()函數需要傳兩個實參,你傳了三個實參
View Code

 

 

b:少傳遞一個實參

def test(x,y):
    print(x)
    print(y)
print("--------少一個參數----")
test(1)
 
#輸出
--------少一個參數----
Traceback (most recent call last):
  File "D:/PycharmProjects/pyhomework/day3/函數_帶參數.py", line 8, in <module>
    test(1)
TypeError: test() missing 1 required positional argument: 'y'  #沒有給y參數傳實參
View Code

 

 

(2)、關鍵字參數

上面的位置參數,看起來有點死,必須形參和實參的位置一一對應,不然就會傳錯參數,為了避免這種問題,就有了關鍵字參數的玩法:關鍵字傳參不需要一一對應,只需要你指定你的哪個形參調用哪一個實參即可;
def test(x,y):
    print(x)
    print(y)
 
print("--------互換前------")
test(x=1,y=2)
print("--------互換后------")
test(y=2,x=1)
 
#輸出
--------互換前------
1
2
--------互換后------
1
2

 

 研究一下位置參數和關鍵字參數結合使用:

1,位置參數在前,關鍵字參數在后

def test(x,y):
    print(x)
    print(y)
 
test(1,y=2)
 
#輸出
1
2

 

def test(x,y,z):
    print(x)
    print(y)
    print(z)
 
test(1,z=2,y=3)
 
#輸出
1
3
2

 

 

 

2、上面的列子是關鍵字傳參傳給y,現在傳給x,代碼如下:

def test(x,y):
    print(x)
    print(y)
 
test(1,x=2)
 
#輸出
Traceback (most recent call last):
  File "D:/PycharmProjects/pyhomework/day3/函數_帶參數.py", line 8, in <module>
    test(1,x=2)
TypeError: test() got multiple values for argument 'x' #給x形參傳的值過多,之前位置參數 就傳實參給x一次,后面關鍵字又傳實參給x,造成報錯

 

 

3 、關鍵字參數在前,位置參數在后:

def test(x,y):
    print(x)
    print(y)
 
test(y=2,1)
 
#輸出
File "D:/PycharmProjects/pyhomework/day3/函數_帶參數.py", line 8
    test(y=2,1)
            ^
SyntaxError: positional argument follows keyword argument # 關鍵字參數在位置參數的前面

 

另外一種,就是關鍵字參數在中間:

def test(x,y,z):
    print(x)
    print(y)
 
test(1,y=2,3)
 
#輸出
 File "D:/PycharmProjects/pyhomework/day3/函數_帶參數.py", line 8
    test(1,y=2,3)
              ^
SyntaxError: positional argument follows keyword argument

 

 

結論:關鍵字參數是不能寫在位置參數前面的。

 

 三、全局變量和局部變量

1、局部變量

局部變量:顧名思義,指在局部生效,定義在函數體內的變量只能在函數里面生效,出個這個函數體,就不能找到它,這個函數就是這個變量的作用域,如下代碼:

name = "apple"

def test(name):
    print("before change:",name)
    name = "bananan"  #局部變量name,只能在這個函數內生效,這個函數就是這個變量的作用域
    print("after change:",name)
 


test(name)
print(name)
 
#輸出
before change: apple
after change: bananan  #局部變量生效

bananan# 外部的變量還是apple,僅函數內的name變成了bananan

 

 

2、全局變量

全局變量:指的是在整個程序中都生效的變量,在整個代碼的頂層聲明:

 

name = "apple"

def test(name):
    print("before change:",name)
    name = "bananan"  #局部變量name,只能在這個函數內生效,這個函數就是這個變量的作用域
    print("after change:",name)
 
def test1(name):
    print(name)

test(name)
test(name1)
print(name)
 
#輸出
before change: apple
after change: bananan  #局部變量生效

apple# 全局變量
apple# 全局變量

 

 

注:全局變量的優先級是低於局部變量的,當函數體內沒有局部變量,才會去找全局變量

3、局部變量改成全局變量

  • 改前用global先聲明一下全局變量
  • 將全局變量重新賦值
name = "apple"

def test(name):
    global name #使用global 聲明全局變量
    print("before change:",name)
    name = "bananan"  #全局變量重新賦值
    print("after change:",name)
 
def test1(name):
    print(name)

test(name)
test(name1)
print(name)
 
#輸出
before change: apple
after change: bananan  

bananan
bannann

 

注:最好不要用global這個關鍵字,因為你用了,其他人調你的函數時,就亂套了,而且還不好調試。

 

4、全局變量定義成列表

names = ['AAAA',"BBBB"]  #定義一個列表
 
def test():
    names[0] = "CCCC"
    print(names)
 
print("--------test-----")
test()
print("------打印names--")
print(names)
 
#輸出
--------test-----
['CCCC', 'BBBB']     #函數內的names輸出
------打印names--
['CCCC', 'BBBB']     #函數外的names輸出

 

注:1、只有字符串和整數是不可以被修改的,如果修改,需要在函數里面聲明global。2、但是復雜的數據類型,像列表(list)、字典(dict)、集合(set)、類(class)都是可以修改的。

 

5、小實驗: 

局部作用域和全局作用域的訪問順序

#局部作用域和全局作用域的訪問順序
x=0
def grandpa():
    x=1
    def dad():
        x=2
        def son():
            x=3
            print(x)
        son()
    dad()
#調用grandpa
grandpa()
 
#輸出
3

注:作用域,只能是從里往外找,一層一層的的找。

 

 

全局變量和局部變量小結:

  1. 在子程序(函數)中定義的變量稱為局部變量,在程序一開始定義的變量稱為全局變量。
  2. 全局變量的作用域是整個程序,局部變量的作用域是定義該變量的子程序(函數)。
  3. 當全局變量和局部變量同名時:在定義局部變量的子程序內,局部變量起作用;在其他地方,全局變量起作用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM