Python基礎10-函數基礎

目錄

函數的定義

函數的返回值

函數的參數

參數的傳遞

參數的默認值

可變長參數

全局變量與局部變量

函數嵌套定義

風溼理論——函數即變量


函數的定義

定義函數的關鍵字def。函數名,本例函數名是test。小括號裏面是參數。冒號後縮進的代碼塊是函數內容。函數的註釋用""",使用雙引號是爲了規範。return返回值。pass說明函數結束,其實pass不加也沒問題,但是爲了規範還是寫上吧。

Python解釋器逐行解釋,如果函數test定義一次以後,再定義一個函數test,那麼就test就以最後一次定義的爲準。

def test(x):
    """
    function test
    :param x: 整數
    :return: 返回x的立方值
    """
    y = x ** 3
    return y
    pass


def test():
    """
    function test
    這就重新定義了函數test
    :return: 9527
    """
    return 9527
    pass


val = test()
print(val)
# 9527

函數的返回值

Python的返回值和Java一樣也是隻有一個返回值。因爲Python有了元組這個容器類型,所以多個返回值可以被轉換爲一個元組返回。看起來可以返回多個值,而且實際上你也可以這麼用。

def func01():
    """
    如果沒有返回值,那麼返回的是None
    :return: None
    """
    msg = "func01"
    print(msg)


def func02():
    """
    返回一個值
    :return: msg
    """
    msg = "func02"
    print(msg)
    return msg


def func03():
    """
    如果返回多個值,那麼返回的是這多個值組成的元組。
    實際上是返回一個值,元組。但是你可以用多個變量來接收這個元組的元素。
    :return: 
    """
    msg = "func03"
    print(msg)
    return msg, [11, 22, 33], 28, "Kevin"


t1 = func01()
t2 = func02()
t3 = func03()
val, li, num, name = func03()
print(t1)
print(t2)
print(t3)
print(val, li, num, name)
# None
# func02
# ('func03', [11, 22, 33], 28, 'Kevin')
# func03 [11, 22, 33] 28 Kevin

函數的參數

參數的傳遞

函數的參數分爲實參和形參。

func04的參數xyz都是形參。形參只在函數被調用時分配內存空間,函數調用結束以後內存空間就被釋放。

函數傳參可以傳位置參數,就是按照形參順序傳參,不能多也不能少。

函數傳參可以傳關鍵字參數,就是形參名=實參,順序無所謂,不能多也不能少。

位置參數和關鍵字參數可以混搭使用。位置參數必須在關鍵字參數前面,傳參總個數不能多也不能少。

def func04(x, y, z):
    print(x, y, z, sep=",")
    return


# 位置參數,按照順序傳參,不能多也不能少
func04(11, 22, 33)
# 關鍵字參數,按照關鍵字傳參,順序無所謂,不能多也不能少
func04(z=33, x=11, y=22)
# 位置參數和關鍵字參數可以混用
# 位置參數 必須在 關鍵字參數 前面,不能多也不能少
func04(11, 22, z=33)

參數的默認值

函數的參數可以有默認值。非默認值參數必須放在默認值參數前面。調用時,非默認參數必須傳值,默認值參數可以不傳值。參數不用默認值時,用關鍵字參數指定哪個參數不用默認值。

def func05(app, db="mysql", os="linux"):
    """
    非默認值參數放在默認值參數前面。
    默認數據庫是mysql,默認操作系統是linux。
    :param app: 應用
    :param db: 數據庫
    :param os: 操作系統
    :return: None
    """
    print("%(app)s, %(db)s, %(os)s." % ({"app": app, "db": db, "os": os}))
    pass


# 默認值參數不用傳輸 
# discuzz, mysql, linux.
func05("discuzz")

# 參數不用默認值時,最好用關鍵字參數,指定哪個參數不是默認的值
# httpd, mysql, freebsd.
func05("httpd", os="freebsd")

可變長參數

傳入多個參數,*對應列表,**對應字典。

函數參數加上*args,函數就可以接收多個位置參數,按照Python規則*args就這麼寫。*args接收位置參數,除去前面的位置參數,多出來的被處理成元組args。如果傳入的是列表,那麼列表就是元組args的一個元素。如果傳入的*列表,那麼就把列表的元素處理成元組args的元素。

def func06(x, y, *args):
    """
    *args接收位置參數,將多個參數處理成元組。
    此時,函數可以接收多個參數,出去前面的位置參數,後面的多個參數處理成元組
    如果傳入的是個列表,那麼這個列表就是元組args的一個元素。
    如果傳入的列表元素都變成args的元素,那麼傳參時需要加*。*對應列表
    :param x:
    :param y:
    :param args:
    :return:
    """
    print(x)
    print(y)
    print(args)
    pass

# 1
# 2
# ()
func06(1, 2)

# 1
# 2
# (3, 4, 5, 6)
func06(1, 2, 3, 4, 5, 6)

# 1
# 2
# ([3, 4, 5, 6],)
func06(1, 2, [3, 4, 5, 6])

1
2
(3, 4, 5, 6)
func06(1, 2, *[3, 4, 5, 6])

函數加上**kwargs,函數就可以接收多個關鍵字參數,按照Python規則就這麼寫。接收的多個關鍵字參數被處理成字典kwargs。如果要傳入字典的話,字典前面加上**。

def func07(x, y, **kwargs):
    """
    *kwargs接收關鍵字參數,將多個關鍵字參數處理成字典。
    此時,函數可以接收多個關鍵字參數,除去前面的位置參數,後面的多個關鍵字參數被處理成字典
    如果傳入的是字典,需要在字典前面加**
    :param x:
    :param y:
    :param kwargs:
    :return:
    """
    print(x, y)
    print(kwargs, kwargs.get("k1"))
    pass


# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, k1="v1", k2="v2")
# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, **{"k1": "v1", "k2": "v2"})

如果函數參數加上了*args和**kwargs,那麼這個函數就可以接收任意的參數了。這樣有利於未來的擴展。接收的參數怎麼處理是函數實現的問題。

def func08(x, y, *args, **kwargs):
    """
    現在這個函數牛逼了
    :param x: 
    :param y: 
    :param args: 
    :param kwargs: 
    :return: 
    """
    print(x, y)
    print(args)
    print(kwargs, kwargs.get("k1"))
    pass


# 1 2
# (3, 4, 5, 6)
# {} None
func08(1, 2, 3, 4, 5, 6)

# 1 2
# ()
# {'a': 5, 'b': 9} None
func08(1, 2, a=5, b=9)

# 1 2
# (3, 4, 11, 22, 33, 44)
# {'k1': 'v1', 'k2': 'v2', 'k3': 9527} v1
func08(1, 2, 3, 4, *[11, 22], *[33, 44], **{"k1": "v1", "k2": "v2"}, k3=9527)

全局變量與局部變量

全局變量作用於全局。局部變量作用於代碼塊。執行函數時,先找局部變量,局部變量找不到再找全局變量。如果要直接訪問全局變量,那麼要用global聲明。Python編程規範,全局變量全部大寫,局部變量全部小寫,這樣以後就不會出現變量名重合的情況了。

name = "Kevin"
name1 = "Tom"


def change_name():
    global name
    name = "Alice"
    name1 = "Jerry"
    print(name, name1)
    pass


# Alice Jerry
# Alice Tom
change_name()
print(name, name1)

函數嵌套定義

函數裏面還可以再定義函數。如果出現global,那麼global變量就是全局變量。這段代碼func12將全局變量name的值從Able改成了Charlie。

name = "Able"


def func11():
    name = "Baker"

    def func12():
        global name
        name = "Charlie"
        pass

    func12()
    print(name)
    pass


print(name)
func11()
print(name)

函數裏global只的就是全局變量,而另一個關鍵字nonlocal指的是上一層的變量。這段代碼,func12裏面將func11的局部變量name的值從Baker改爲Charlie。

name = "Able"


def func11():
    name = "Baker"

    def func12():
        nonlocal name
        name = "Charlie"
        pass

    func12()
    print(name)
    pass


print(name)
func11()
print(name)
# Able
# Charlie
# Able

風溼理論——函數即變量

Python的風溼理論?靠,什麼鬼名字。這裏的意思是函數都可以看成是函數名的字符串。只要在這個字符串裏面的變量或者函數曾經出現在內存中,就可以找到,繼續執行不會報錯。

這個例子中func14雖然定義在func13之後,但是根據風溼理論,程序逐行執行,func13和func14都會先作爲變量保存在內存中。調用func13時,執行func13代碼塊,遇到調用func14,因爲func14已經存在了,找得到,所以不會報錯。

def func13():
    print("from func13")
    func14()
    pass


def func14():
    print("from func14")
    pass


# from func13
# from func14
func13()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章