1. 程式人生 > >python學習06-函數

python學習06-函數

users eth 成功 視頻 rgs 情況 也會 嵌套 linu

一、函數的定義及語法

函數一詞來源於數學,編程中的"函數"與數學中的函數與歐很大的不同。
  (BASIC中叫subroutine,C中叫function,java中叫method)

定義:函數是指將一組語句的集合通過一個名字(函數名)封裝起來,想執行這個函數,只需調用其函數名即可。 

特性:

  1. 減少重復代碼
  2. 使程序變得可擴展
  3. 使得程序變得易維護
# 無參函數
def sayhi(): # 函數名(小寫即可)
    print("Hello,I‘m nobody!")

sayhi()   # 調用函數,函數名指向上述代碼指向的內存位置,加上括號才是執行代碼
print(sayhi)   #
函數sayhi指向的內存地址 # 單個參數的函數 def sayhi(name): print("hello",name) print("my name is black girl....", name) sayhi("tracy") # 多個參數函數 def calc(x,y): # 定義算數函數 res = x**y return res # 返回函數執行結果 a,b = 5,8 c = calc(a,b) # 結果賦值給變量c print(c) calc(2,10) # 直接寫入參數
二、函數的參數

參數的作用:

可以讓函數更靈活,不只能做死動作,還可以根據調用時傳參的不同來決定函數內部的執行流程。

形參:只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量

實參:可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值

def calc(x,y):   # 形參
    res = x**y
    return res
a,b = 3,5
c = calc(a,b)    # 實參
print(c)
d 
= calc(2,3) # 實參

默認參數:

def stu_register(name,age,country,course):
    print("註冊學生信息".center(50,-))
    print("姓名:",name)
    print("age:" ,age)
    print("國籍",country)
    print("課程",course)

stu_register("山炮",22,"CN","python_devops")
stu_register("豐收",23,"CN","linux")

‘‘‘
    由於很多人國籍都是中國,可以將country設置為默認參數
    默認參數:
‘‘‘
def stu_register(name,age,course,country="CN"):  # 非默認參數不能跟在默認參數後面
    print("registration info".center(50,-))
    print(name,age,country,course)

stu_register("jack",22,c++)     # 實參和形參按順序一一對應
stu_register("rain",32,dance,Korean)
stu_register("Alfa",21,python)

關鍵字參數:

  應用場景:正常情況下,給函數傳參數要按順序,不想按順序可以用關鍵參數
  定義:指定了參數名的參數就叫關鍵參數
     關鍵參數必須放在位置參數(以位置順序確定對應關系的參數)之後

def stu_register(name,age,course,country=CN):
    print("註冊學生信息".center(50,-))
    print("姓名:",name)
    print("age:" ,age)
    print("國籍",country)
    print("課程",course)

stu_register("綺珊",course=Python,age=22,country=JP)  # 後三個均為為關鍵參數置於name位置參數之後
# stu_register("杉樹",course=‘Python‘,22,country=‘JP‘)    # 22為位置參數不能放在關鍵參數course之後
# stu_register("曼玉",22,age=25,country=‘JP‘)    # age獲得多個賦

非固定參數(動態參數):

  形式參數中出現*,傳遞的參數就可以不再是固定個數,會將傳過來的所有參數打包為元組。

def send_alert(msg,*users):
    for u in users:
        print(報警發送給,u)

# 方式一:
# 報警,十個運維人員
send_alert(註意系統資源別浪了,Alex,jack,tracy,wood)


# 方式二:
# send_alert(‘註意內存緊張‘,[‘alex‘,‘jack‘,‘tracy‘,‘wood‘])  # 傳入的參數是數據
send_alert(註意內存緊張,*[alex,jack,tracy,wood])   # 傳入的參數是數組內的元素
# 傳入的參數由([‘alex‘,‘jack‘,‘tracy‘,‘wood‘]) ————>(‘alex‘,‘jack‘,‘tracy‘,‘wood‘)

  如果動態參數後還有參數

# 方法一:
def send_redalert(msg,*users,age):
    for u in users:
        print(CPU緊張,u)
# send_redalert("alex","rain",22)   # 22也會傳遞給*users
send_redalert("alex","rain",age=22)

#  方法二:
def func(name,*args,**kwargs):
    print(name,args,kwargs)

func(Alex,22,tesla,500w,addr=湖北,num=123332313)
# Alex (22, ‘tesla‘, ‘500w‘) {‘addr‘: ‘湖北‘, ‘num‘: 123332313}

d = {degree:primary school}
func(Peiqi,**d)

三、函數的返回值

返回值:函數外部的代碼要想獲取函數的執行結果,可以在函數裏用return語句把結果返回。
註意:
  1、函數在執行過程中只要遇到return語句,就會停止執行並返回結果,so可以理解為return語句代表著函數的結束
  2、如果未在函數中指定return,那這個函數的返回值為None

def stu_register(name,age,course=PY,country=CN):
    print("註冊學生信息".center(50,-))
    print("姓名:", name)
    print("age:", age)
    print("國籍", country)
    print("課程", course)
    if age > 22:
        return False
    else:
        return True

registration_status = stu_register(阿斯頓,22,course="全棧開發",country=JP)

if registration_status:
    print("註冊成功".center(50,-))
else:
    print("too old to be a student.")

‘‘‘
    執行到return語句後,停止執行函數並返回結果
‘‘‘
def stu_register(name,age,course):
    print(name,age,course)
    #
    # if age > 22:
    #     return ‘sdfsf‘  # 返回值可以是任意值
    # else:
    #     return True
    #
    # return None      # 到return語句後,停止執行函數並返回結果
    # print(‘hahah‘)
    # return 1
    return [name,age]
status = stu_register(Peiqi,29,安保)
print(status)

四、全局和局部變量

局部變量:函數內定義的變量,只能在局部生效
全局變量:定義在函數外部一級代碼的變量,整個程序可用(由上到下可用)
     在函數內部可以引用全局變量。
變量查找順序:如果全局和局部都有一個變量,函數查找變量的順序是由內而外的。兩個函數間互不可見

name = "Black girl"       # 全局變量

def change_name():
    # global name         # (不建議使用global)在函數內修改全局變量,不能放在函數內局部變量後面
    name = "黑色的姑娘"     # 局部變量
    print("",name,"裏面...",id(name))

change_name()
print(name,id(name))   # 與函數內的變量內容完全不同
‘‘‘
輸出結果:
    在 黑色的姑娘 裏面... 4302993904
    Black girl 4316351984
‘‘‘

函數內可以修改字典、列表、集合、對象、類、元組內的列表

names = [Alex,Black Girl,Peiqi]
def change_name():
    names = [Alex]
    del names[2]      # names整體的內存地址不能修改只能引用,但其內部的元素是可以修改的
    names[1] = "黑姑娘"
    print(names)

change_name()
print(names)
‘‘‘
輸出結果:
    [‘Alex‘, ‘黑姑娘‘]
    [‘Alex‘, ‘黑姑娘‘]
‘‘‘
  • 在函數中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。
  • 全局變量作用域是整個程序,局部變量作用域是定義該變量的函數。
  • 當全局變量與局部變量同名時,在定義局部變量的函數內,局部變量起作用;在其它地方全局變量起作用。
五、作用域(scope)

作用域定義:一段程序代碼中所用到的名字並不總是有效/可用的,而限定這個名字的可用性的代碼範圍就是這個名字的作用域

  • python中一個函數就是一個作用域,局部變量放置在其作用域中
  • C# Java中作用域{}
  • 代碼定義完成後,作用域已經完成,作用域鏈向上查找
age = 18
def func1():
    age = 73
    def func2():
        age = 84
        print(age)

    return 666

val = func1()
print(val)
‘‘‘
輸出:666
‘‘‘

# 函數名可以當作返回值 age = 18 def func1(): age = 73 def func2():... return func2 # 返回一個函數名# val = func1() print(val) ‘‘‘ 輸出:<function func1.<locals>.func2 at 0x101462598> ‘‘‘ # 代碼寫完之後作用域已經生成,不管函數名傳到哪裏,只要執行都回回定義的地方往上找 age = 18 def func1(): age = 73 def func2(): print(age) return func2 # 返回一個函數名不帶括號 val = func1() val() ‘‘‘ 輸出結果:73 ‘‘‘
六、嵌套函數

嵌套函數,就是指在某些情況下,您可能需要將某函數作為另一函數的參數使用。

  • 函數內部可以再次定義函數
  • 執行需要被調用
  • 嵌套函數尋找變量的順序(一層一層往上找)

def func1():
    print(alex)

    def func2():
        print(eric)

func1()
‘‘‘
輸出:
    alex
‘‘‘

def func1():
    print(alex)

    def func2():
        print(eric)

    func2()

func1()
‘‘‘
輸出:
    alex
    eric
‘‘‘
尋找變量,先找自己的函數內,沒有就找全局變量(一層一層往上找)
age = 19

def func1():
    # age = 73
    print(age)   # 尋找變量,先找自己的函數內,沒有就找全局變量(一層一層往上找)
    def func2():
        age = 84
        print(age)   # 尋找變量,優先自己函數、再找父級、爺爺級,最後找全局變量
    func2()
func1()
# 輸出: 73  84
‘‘‘
    示例
‘‘‘
age1 = 19
def func1():
    age1 = 73
    def func2():
        print(age1)
    func2()

局部變量位置調整 第三章第20視頻需要重新看

age = 19
def func1():
    def func2():
        print(age)
    func2()
    age = 73
func1()
‘‘‘
    執行報錯,73在func2後面,func2不知道該取哪個參數
‘‘‘

python學習06-函數