成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Python函數(shù)如何自定義

這篇文章主要介紹“Python函數(shù)如何自定義”,在日常操作中,相信很多人在Python函數(shù)如何自定義問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python函數(shù)如何自定義”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、網(wǎng)站設(shè)計、外貿(mào)營銷網(wǎng)站建設(shè)與策劃設(shè)計,濱海網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:濱海等地區(qū)。濱海做網(wǎng)站價格咨詢:18982081108

函數(shù)

函數(shù)是一個非常重要的概念,它們存在于所有編程語言中。函數(shù)允許我們定義一個動作(代碼塊),然后執(zhí)行該動作任意次數(shù),而無需遵循DRY原則重復(fù)自己。到目前為止,我一直在使用Python提供的一些內(nèi)置函數(shù),例如printinputlen等。

什么是函數(shù)?函數(shù)(function)是用于完成特定任務(wù)的程序代碼的自包含單元。在面向?qū)ο缶幊痰念愔?,函?shù)通常被稱作方法。不同的函數(shù)在程序中扮演著不同的角色,起著不同的作用,執(zhí)行不同的動作。比如print()函數(shù)可以將對象打印到屏幕上;還有一些函數(shù)能夠返回一個值以供程序使用,比如len()將可計算長度的對象的元素個數(shù)返回給程序。

那么,為什么要使用函數(shù)呢?

第一、函數(shù)的使用可以重用代碼,省去重復(fù)性代碼的編寫,提高代碼的重復(fù)利用率。如果程序中需要多次使用某種特定的功能,那么只需要編寫一個合適的函數(shù)就可以了。程序可以在任何需要的地方調(diào)用該函數(shù),并且同一個函數(shù)可以在不同的程序中調(diào)用,就像我們經(jīng)常使用的print()和input()函數(shù)一樣。

第二、函數(shù)能封裝內(nèi)部實現(xiàn),保護內(nèi)部數(shù)據(jù),實現(xiàn)對用戶的透明。很多時候,我們把函數(shù)看做“黑盒子”,即對應(yīng)一定的輸入會產(chǎn)生特定的結(jié)果或返回某個對象。往往函數(shù)的使用者并不是函數(shù)的編寫者,函數(shù)的使用者對黑盒子的內(nèi)部行為并不需要考慮,可以把精力投入到自身業(yè)務(wù)邏輯的設(shè)計而不是函數(shù)的實現(xiàn)細節(jié)。只有函數(shù)的設(shè)計者或者說編寫者,才需要考慮函數(shù)內(nèi)部實現(xiàn)的細節(jié),如何暴露對外的接口,返回什么樣的數(shù)據(jù),也就是API的設(shè)計。

第三、即使某種功能在程序中只使用一次,將其以函數(shù)的形式實現(xiàn)也是有必要的,因為函數(shù)使得程序模塊化,從“一團散沙”變成“整齊方隊”,從而有利于程序的閱讀、調(diào)用、修改和完善。例如,假設(shè)你正在編寫一個實現(xiàn)下面功能的程序:

  • 讀入一行數(shù)字

  • 對數(shù)字進行排序

  • 找到它們的平均值

  • 打印出一個柱狀圖

是時候創(chuàng)建一個函數(shù)了。

def blow_fire(): # 函數(shù)定義
  print('fire ???? ???? ????')

blow_fire() # 函數(shù)調(diào)用
blow_fire() # 可以調(diào)用多次

參數(shù)

上面的函數(shù)看起來不錯吧,但它也有一些限制。它只能執(zhí)行相同的操作。讓我們使它更具可擴展性,并通過向其傳遞一些數(shù)據(jù)來使其隨意執(zhí)行操作。

在定義函數(shù)時,當(dāng)我們向其提供一些數(shù)據(jù)以基于該數(shù)據(jù)執(zhí)行某些操作時,提供的數(shù)據(jù)稱為參數(shù)??梢詾楹瘮?shù)提供任意數(shù)量的參數(shù)。

絕大多數(shù)函數(shù)接收一定數(shù)量的參數(shù),然后根據(jù)實際調(diào)用時提供的參數(shù)的值的不同,輸出不同的結(jié)果。前面我們說過,將函數(shù)內(nèi)部的參數(shù)名字,定義得和外部變量的名字一樣是一種不好的習(xí)慣,它容易混淆思維,甚至發(fā)生錯誤。通常我們定義和給函數(shù)傳遞參數(shù)是這樣的:

x, y, z = 1, 2, 3

def add(a, b, c):

    return a+b+c

add(x, y, x)        # 使用變量,傳遞參數(shù)
add(4, 5, 6)        # 直接傳遞值也是可以的。

在上面的例子中,a,b,c叫做形式參數(shù),簡稱形參。而x,y,z和4,5,6叫做實際參數(shù),簡稱實參,也就是實際要傳遞的值。而我們通常討論的參數(shù),指的都是形參。

定義函數(shù)時,參數(shù)的名字和位置確定下來,函數(shù)的接口就固定了。對于函數(shù)的調(diào)用者來說,只需要知道如何傳遞正確的參數(shù),以及函數(shù)將返回什么樣的值就夠了,函數(shù)內(nèi)部的復(fù)雜邏輯被封裝起來,調(diào)用者無需了解。Python函數(shù)的參數(shù)定義靈活度非常大。除了正常定義的位置參數(shù)外,還可以使用默認參數(shù)、動態(tài)參數(shù)和關(guān)鍵字參數(shù),這些都是形參的種類。

位置參數(shù)

也叫必傳參數(shù),順序參數(shù),是最重要的,也是必須在調(diào)用函數(shù)時明確提供的參數(shù)!位置參數(shù)必須按先后順序,一一對應(yīng),個數(shù)不多不少的傳遞!

上面例子中的a,b,c就是位置參數(shù),我們在使用add(4, 5, 6)調(diào)用時,就是將4傳給a,5傳給b,6傳給c的一一對應(yīng)傳遞。類似add(4, 5, 6, 7)add(4)add(5, 4, 6)這種“畫蛇添足”、“缺胳膊少腿”和“嫁錯郎”類型的調(diào)用都是錯誤的。其中,add(5, 4, 6)的調(diào)用在語法上沒問題,但是輸出結(jié)果可能和預(yù)期的不一致。

注意: Python在做函數(shù)參數(shù)傳遞的時候不會對數(shù)據(jù)類型進行檢查,理論上你傳什么類型都可以!

def add(a, b, c):
    return a+b+c

result = add("haha", 2,  3)

但是,上面的add函數(shù),如果你傳遞了一個字符串和兩個數(shù)字,結(jié)果是彈出異常,因為字符串無法和數(shù)字相加。這就是Python的弱數(shù)據(jù)類型和動態(tài)語言的特點。在簡單、方便的時候,需要你自己去實現(xiàn)數(shù)據(jù)類型檢查。

Traceback (most recent call last):
  File "F:/Python/pycharm/201705/func.py", line 33, in <module>
    result = add("haha", 2,  3)
  File "F:/Python/pycharm/201705/func.py", line 31, in add
    return a+b+c
TypeError: must be str, not int

默認參數(shù)

在函數(shù)定義時,如果給某個參數(shù)提供一個默認值,這個參數(shù)就變成了默認參數(shù),不再是位置參數(shù)了。在調(diào)用函數(shù)的時候,我們可以給默認參數(shù)傳遞一個自定義的值,也可以使用默認值。

def power(x, n = 2):
    return x**n

ret1 = power(10)   # 使用默認的參數(shù)值n=2
ret2 = power(10, 4)  # 將4傳給n,實際計算10**4的值

上面例子中的n就是個默認參數(shù)。默認參數(shù)可以簡化函數(shù)的調(diào)用,在為最常用的情況提供簡便調(diào)用的同時,還可以在特殊情況時傳遞新的值。但是在設(shè)置默認參數(shù)時,有幾點要注意:

  • 默認參數(shù)必須在位置參數(shù)后面!

如果你違反了這點,在語法層面直接是通不過的。

# 這是一個錯誤的例子
def power(n = 2,x):
    return x**n
  • 當(dāng)有多個默認參數(shù)的時候,通常將更常用的放在前面,變化較少的放后面。

def student(name, sex, age, classroom="101", tel="88880000", address="..."):
    pass
  • 在調(diào)用函數(shù)的時候,盡量給實際參數(shù)提供默認參數(shù)名。

def student(name, sex, age, classroom="101", tel="88880000", address="..."):
    pass

student('jack','male',17)       # 其它全部使用默認值
student('tom','male',18,'102','666666','beijing')    # 全部指定默認參數(shù)的值
student('mary','female',18,'102',tel='666666')  # 挑著來
student('mary','female',18,tel='666666','beijing')   #  這是錯誤的參數(shù)傳遞方式
student("mary","female",18,tel="666666",address="beijing")

注意最后兩種調(diào)用方式,倒數(shù)第二種是錯誤的,而最后一種是正確的。為什么會這樣?因為一切沒有提供參數(shù)名的實際參數(shù),都會當(dāng)做位置參數(shù)按順序從參數(shù)列表的左邊開頭往右匹配!

  • 使用參數(shù)名傳遞參數(shù)

通常我們在調(diào)用函數(shù)時,位置參數(shù)都是按順序先后傳入,而且必須在默認參數(shù)前面。但如果在位置參數(shù)傳遞時,給實參指定位置參數(shù)的參數(shù)名,那么位置參數(shù)也可以不按順序調(diào)用,例如:

def student(name, age, classroom, tel, address="..."):
    pass

student(classroom=101, name="Jack", tel=66666666, age=20)

注意指定的參數(shù)名必須和位置參數(shù)的名字一樣。

  • 默認參數(shù)盡量指向不變的對象!

使用不可變的數(shù)據(jù)類型作為默認值!

def func(a=None):
    # 注意下面的if語句
    if a is None:
        a = []
    a.append("A")
    return a

print(func())
print(func())
print(func())

將默認參數(shù)a設(shè)置為一個類似None,數(shù)字或字符串之類的不可變對象。在函數(shù)內(nèi)部,將它轉(zhuǎn)換為可變的類型,比如空列表。這樣一來,不管調(diào)用多少次,運行結(jié)果都是['A']了。

動態(tài)參數(shù)

顧名思義,動態(tài)參數(shù)就是傳入的參數(shù)的個數(shù)是動態(tài)的,可以是1個、2個到任意個,還可以是0個。在不需要的時候,你完全可以忽略動態(tài)函數(shù),不用給它傳遞任何值。

Python的動態(tài)參數(shù)有兩種,分別是*args**kwargs,這里面的關(guān)鍵是一個和兩個星號的區(qū)別,而不是argskwargs在名字上的區(qū)別,實際上你可以使用*any**whatever的方式。但就如self一樣,默認大家都使用*args**kwargs。

注意:動態(tài)參數(shù),必須放在所有的位置參數(shù)和默認參數(shù)后面!

def func(name, age, sex='male', *args, **kwargs):
    pass
*args

一個星號表示接收任意個參數(shù)。調(diào)用時,會將實際參數(shù)打包成一個元組傳入形式參數(shù)。如果參數(shù)是個列表,會將整個列表當(dāng)做一個參數(shù)傳入。例如:

def func(*args):
    for arg in args:
        print(arg)

func('a', 'b', 'c')

li = [1, 2, 3]
func(li)

運行結(jié)果是:

a
b
c
[1, 2, 3]

通過循環(huán)args,我們可以獲得傳遞的每個參數(shù)。但是li這個列表,我們本意是讓它內(nèi)部的1,2,3分別當(dāng)做參數(shù)傳遞進去,但實際情況是列表本身被當(dāng)做一個整體給傳遞進去了。怎么辦呢?使用一個星號!調(diào)用函數(shù),傳遞實參時,在列表前面添加一個星號就可以達到目的了。實際情況是,不光列表,任何序列類型數(shù)據(jù)對象,比如字符串、元組都可以通過這種方式將內(nèi)部元素逐一作為參數(shù),傳遞給函數(shù)。而字典,則會將所有的key逐一傳遞進去。

def func(*args):
    for arg in args:
        print(arg)

li = [1, 2, 3]
func(*li)
**kwargs

兩個星表示接受鍵值對的動態(tài)參數(shù),數(shù)量任意。調(diào)用的時候會將實際參數(shù)打包成字典。例如:

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])
        print(type(kwg))

func(k1='v1', k2=[0, 1, 2])

運行結(jié)果是:

k1 v1
<class 'str'>
k2 [0, 1, 2]
<class 'str'>

而如果我們這樣傳遞一個字典dic呢?我們希望字典內(nèi)的鍵值對能夠像上面一樣被逐一傳入。

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])

dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(dic)

實際結(jié)果卻是彈出錯誤,為什么?

Traceback (most recent call last):
  File "F:/Python/pycharm/201705/func.py", line 10, in <module>
    func(dic)
TypeError: func() takes 0 positional arguments but 1 was given

因為這時候,我們其實是把dic當(dāng)做一個位置參數(shù)傳遞給了func函數(shù)。而func函數(shù)并不接收任何位置函數(shù)。那怎么辦呢?使用兩個星號!

def func(**kwargs):
    for kwg in kwargs:
        print(kwg, kwargs[kwg])

dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(**dic)

有了前面一個星號的基礎(chǔ),這里我們應(yīng)該很好理解了。兩個星號能將字典內(nèi)部的鍵值對逐一傳入**kwargs

“萬能”參數(shù)

當(dāng)*args**kwargs組合起來使用,理論上能接受任何形式和任意數(shù)量的參數(shù),在很多代碼中我們都能見到這種定義方式。需要注意的是,*args必須出現(xiàn)在**kwargs之前。

def func(*args, **kwargs):

    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = [1, 2, 3]
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(*lis, **dic)

現(xiàn)在我們結(jié)合一下普通參數(shù)和萬能參數(shù),看看會有什么情況發(fā)生:

def func(a, b, c=1, *args, **kwargs):
    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = ['aaa', 'bbb', 'ccc']
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(1, 2, *lis, **dic)

打印結(jié)果是:

bbb
ccc
k1 v1
k2 v2

列表lis中的第一個元素‘a(chǎn)aa’怎么沒有打印出來?

我們改一下代碼,打印一下參數(shù)c的結(jié)果就知道了:

def func(a, b, c=1, *args, **kwargs):
    print('c的值是:', c)
    for arg in args:
        print(arg)

    for kwg in kwargs:
        print(kwg, kwargs[kwg])


lis = ['aaa', 'bbb', 'ccc']
dic = {
    'k1': 'v1',
    'k2': 'v2'
}

func(1, 2, *lis, **dic)

打印結(jié)果為:

c的值是: aaa
bbb
ccc
k1 v1
k2 v2

原來,lis的第一個元素被傳遞給參數(shù)c了!這就是Python的參數(shù)傳遞規(guī)則之一。

關(guān)鍵字參數(shù)

對于*args**kwargs參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的參數(shù)。比如:

def func(*args):
    pass

func("haha", 1, [], {})
func(1,2,3,4,5,6)

對于這樣的參數(shù)傳遞方式,雖然靈活性很大,但是風(fēng)險也很大,可控性差,必須自己對參數(shù)進行過濾和判定。例如下面我只想要姓名、年齡和性別,就要自己寫代碼檢查:

def student(name, age, **kwargs):
    if 'sex' in kwargs:
        student_sex = kwargs['sex']

但是實際上,用戶任然可以隨意調(diào)用函數(shù),比如student("jack", 18, xxx='male'),并且不會有任何錯誤發(fā)生。而我們實際期望的是類似student("jack", 18, sex='male')的調(diào)用。那么如何實現(xiàn)這種想法呢?

可以用關(guān)鍵字參數(shù)!關(guān)鍵字參數(shù)前面需要一個特殊分隔符*和位置參數(shù)及默認參數(shù)分隔開來,*后面的參數(shù)被視為關(guān)鍵字參數(shù)。在函數(shù)調(diào)用時,關(guān)鍵字參數(shù)必須傳入?yún)?shù)名,這和位置參數(shù)不同。如果沒有傳入?yún)?shù)名,調(diào)用將報錯。不同于默認參數(shù),關(guān)鍵字參數(shù)必須傳遞,但是關(guān)鍵字參數(shù)也可以有缺省值,這時就可以不傳遞了,從而簡化調(diào)用。

我們把前面的函數(shù)改寫一下:

def student(name, age, *, sex):
    pass

student(name="jack", age=18, sex='male')

注意函數(shù)的定義體首行。

如果函數(shù)定義中已經(jīng)有了一個*args參數(shù),后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個特殊分隔符*了。

def student(name, age=10, *args, sex, classroom, **kwargs):
    pass

student(name="jack", age=18, sex='male', classroom="202", k1="v1")

Python的函數(shù)參數(shù)種類多樣、形態(tài)多變,既可以實現(xiàn)簡單的調(diào)用,又可以傳入非常復(fù)雜的參數(shù)。需要我們多下功夫,多寫實際代碼,多做測試,逐步理清并熟練地使用參數(shù)。

返回

return是 Python 中的一個關(guān)鍵字,用于從函數(shù)返回值。為了使函數(shù)更有用,它需要根據(jù)表達式的計算返回一些值。如果未指定 return 語句,或者 return 語句的表達式的計算結(jié)果未計算為數(shù)據(jù)類型,則該函數(shù)將返回None 。在 JavaScript 世界中,這個None可以鏈接到void

return語句終止該函數(shù)并退出該函數(shù)。return

def multiplier(num1, num2):
  return num1 * num2

result = multiplier(2,3)
print(result) # 6

是時候使用return語句做一些很酷的事情了。

def sum(num1):
  def child(num2):
    return num1 + num2
  return child

add_10 = sum(10)
print(add_10(20)) # 30  (Closure!!!)
print(add_10(50)) # 60
print(add_10(100)) # 110

我剛剛驗證了Python中也有閉包的概念,就像在JavaScript中一樣。它在創(chuàng)建工廠功能方面非常有效。在上面的代碼塊中,我能夠創(chuàng)建一個通用函數(shù)add_10,并向其傳遞動態(tài)參數(shù)以生成不同的結(jié)果。這是多么酷啊!

下周將在學(xué)習(xí)Python中的函數(shù)式編程概念時對此進行更多探討。

方法只是在對象內(nèi)部定義的函數(shù),或者換句話說,它們由對象“擁有”。使用對象名后跟.運算符調(diào)用它們以執(zhí)行或調(diào)用它們。

return可以返回什么?

  • 什么都不返回,僅僅return:return

  • 數(shù)字/字符串/任意數(shù)據(jù)類型:return 'hello'

  • 一個表達式:return 1+2

  • 一個判斷語句:return 100 > 99

  • 一個變量:return a

  • 一個函數(shù)調(diào)用:return func()

  • 甚至是返回自己?。?code>return self

  • 多個返回值,以逗號分隔:return a, 1+2, "hello"

簡而言之,函數(shù)可以return幾乎任意Python對象。

文檔注釋

在某些特定的位置,用三引號包括起來的部分,也被當(dāng)做注釋。但是,這種注釋有專門的作用,用于為__doc__提供文檔內(nèi)容,這些內(nèi)容可以通過現(xiàn)成的工具,自動收集起來,形成幫助文檔。比如,函數(shù)和類的說明文檔:

def func(a, b):
    """
    這個是函數(shù)的說明文檔。
    :param a: 加數(shù)
    :param b: 加數(shù)
    :return: 和
    """
    return a + b


class Foo:
    """
    這個類初始化了一個age變量
    """
    def __init__(self, age):
        self.age = age

需要強調(diào)的是這類注釋必須緊跟在定義體下面,不能在任意位置。

作用域

簡單來說,作用域意味著“我有權(quán)訪問哪些變量?這是解釋器在讀取代碼以查找變量范圍時提出的問題。在Python中,變量具有函數(shù)作用域,這意味著在函數(shù)內(nèi)部定義的變量不能在函數(shù)外部訪問。

作用域指的是變量的有效范圍。變量并不是在哪個位置都可以訪問的,訪問權(quán)限取決于這個變量是在哪里賦值的,也就是在哪個作用域內(nèi)的。

通常而言,在編程語言中,變量的作用域從代碼結(jié)構(gòu)形式來看,有塊級、函數(shù)、類、模塊、包等由小到大的級別。但是在Python中,沒有塊級作用域,也就是類似if語句塊、for語句塊、with上下文管理器等等是不存在作用域概念的,他們等同于普通的語句。

num = 1
def confusing_function():
    num = 10
    return num

print(num) # 1 => Global Scope
print(confusing_function()) # 10 => Local Scope

這些是Python解釋器遵循的作用域規(guī)則:

  • 從本地開始。變量是否存在?然后獲取該值。如果沒有,請繼續(xù)

  • 變量是否在父函數(shù)本地作用域中定義?如果存在,則獲取值,否則繼續(xù)

  • 全局范圍內(nèi)是否存在該變量?如果存在,則獲取值,否則繼續(xù)

  • 該變量是內(nèi)置函數(shù)嗎?獲取值否則退出

通常,函數(shù)內(nèi)部的變量無法被函數(shù)外部訪問,但內(nèi)部可以訪問;類內(nèi)部的變量無法被外部訪問,但類的內(nèi)部可以。通俗來講,就是內(nèi)部代碼可以訪問外部變量,而外部代碼通常無法訪問內(nèi)部變量。

變量的作用域決定了程序的哪一部分可以訪問哪個特定的變量名稱。Python的作用域一共有4層,分別是:

  • L (Local) 局部作用域

  • E (Enclosing) 閉包函數(shù)外的函數(shù)中

  • G (Global) 全局作用域

  • B (Built-in) 內(nèi)建作用域

x = int(2.9)  # 內(nèi)建作用域,查找int函數(shù)

global_var = 0  # 全局作用域
def outer():
    out_var = 1  # 閉包函數(shù)外的函數(shù)中
    def inner():
        inner_var = 2  # 局部作用域

前面說的都是變量可以找得到的情況,那如果出現(xiàn)本身作用域沒有定義的變量,那該如何尋找呢?

Python以L –> E –> G –>B的規(guī)則查找變量,即:在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全局找,最后去內(nèi)建中找。如果這樣還找不到,那就提示變量不存在的錯誤。例如下面的代碼,函數(shù)func內(nèi)部并沒有定義變量a,可是print函數(shù)需要打印a,那怎么辦?向外部尋找!按照L –> E –> G –>B的規(guī)則,層層查詢,這個例子很快就從外層查找到了a,并且知道它被賦值為1,于是就打印了1。

a = 1

def func():
    print(a)

全局變量和局部變量

定義在函數(shù)內(nèi)部的變量擁有一個局部作用域,被叫做局部變量,定義在函數(shù)外的擁有全局作用域的變量,被稱為全局變量。(類、模塊等同理)

所謂的局部變量是相對的。局部變量也有可能是更小范圍內(nèi)的變量的外部變量。

局部變量只能在其被聲明的函數(shù)內(nèi)部訪問,而全局變量可以在整個程序范圍內(nèi)訪問。調(diào)用函數(shù)時,所有在函數(shù)內(nèi)聲明的變量名稱都將被加入到作用域中。

a = 1               # 全局變量

def func():
    b = 2           # 局部變量
    print(a)        # 可訪問全局變量a,無法訪問它內(nèi)部的c

    def inner():
        c = 3       # 更局部的變量
        print(a)    # 可以訪問全局變量a
        print(b)    # b對于inner函數(shù)來說,就是外部變量
        print(c)

global和nonlocal關(guān)鍵字

我們先看下面的例子:

total = 0                        # total是一個全局變量

def plus( arg1, arg2 ):
    total = arg1 + arg2          # total在這里是局部變量.
    print("函數(shù)內(nèi)局部變量total=  ", total)
    print("函數(shù)內(nèi)的total的內(nèi)存地址是: ", id(total))
    return total

plus(10, 20)
print("函數(shù)外部全局變量total= ", total)
print("函數(shù)外的total的內(nèi)存地址是: ", id(total))

很明顯,函數(shù)plus內(nèi)部通過total = arg1 + arg2語句,新建了一個局部變量total,它和外面的全局變量total是兩碼事。而如果我們,想要在函數(shù)內(nèi)部修改外面的全局變量total呢?使用global關(guān)鍵字!

global:指定當(dāng)前變量使用外部的全局變量

total = 0                        # total是一個全局變量

def plus( arg1, arg2 ):
    global total    # 使用global關(guān)鍵字申明此處的total引用外部的total
    total = arg1 + arg2          
    print("函數(shù)內(nèi)局部變量total=  ", total)
    print("函數(shù)內(nèi)的total的內(nèi)存地址是: ", id(total))
    return total

plus(10, 20)
print("函數(shù)外部全局變量total= ", total)
print("函數(shù)外的total的內(nèi)存地址是: ", id(total))

打印結(jié)果是:

函數(shù)內(nèi)局部變量total=   30
函數(shù)內(nèi)的total的內(nèi)存地址是:  503494624
函數(shù)外部全局變量total=  30
函數(shù)外的total的內(nèi)存地址是:  503494624

我們再來看下面的例子:

a = 1
print("函數(shù)outer調(diào)用之前全局變量a的內(nèi)存地址: ", id(a))

def outer():
    a = 2
    print("函數(shù)outer調(diào)用之時閉包外部的變量a的內(nèi)存地址: ", id(a))
    def inner():
        a = 3
        print("函數(shù)inner調(diào)用之后閉包內(nèi)部變量a的內(nèi)存地址: ", id(a))
    inner()
    print("函數(shù)inner調(diào)用之后,閉包外部的變量a的內(nèi)存地址: ", id(a))
outer()
print("函數(shù)outer執(zhí)行完畢,全局變量a的內(nèi)存地址: ", id(a))

如果你將前面的知識點都理解通透了,那么這里應(yīng)該沒什么問題,三個a各是各的a,各自有不同的內(nèi)存地址,是三個不同的變量。打印結(jié)果也很好的證明了這點:

函數(shù)outer調(diào)用之前全局變量a的內(nèi)存地址:  493204544
函數(shù)outer調(diào)用之時閉包外部的變量a的內(nèi)存地址:  493204576
函數(shù)inner調(diào)用之后閉包內(nèi)部變量a的內(nèi)存地址:  493204608
函數(shù)inner調(diào)用之后,閉包外部的變量a的內(nèi)存地址:  493204576
函數(shù)outer執(zhí)行完畢,全局變量a的內(nèi)存地址:  493204544

那么,如果,inner內(nèi)部想使用outer里面的那個a,而不是全局變量的那個a,怎么辦?用global關(guān)鍵字?先試試看吧:

a = 1
print("函數(shù)outer調(diào)用之前全局變量a的內(nèi)存地址: ", id(a))
def outer():
    a = 2
    print("函數(shù)outer調(diào)用之時閉包外部的變量a的內(nèi)存地址: ", id(a))
    def inner():
        global a   # 注意這行
        a = 3
        print("函數(shù)inner調(diào)用之后閉包內(nèi)部變量a的內(nèi)存地址: ", id(a))
    inner()
    print("函數(shù)inner調(diào)用之后,閉包外部的變量a的內(nèi)存地址: ", id(a))
outer()
print("函數(shù)outer執(zhí)行完畢,全局變量a的內(nèi)存地址: ", id(a))

運行結(jié)果如下,很明顯,global使用的是全局變量a。

函數(shù)outer調(diào)用之前全局變量a的內(nèi)存地址:  494384192
函數(shù)outer調(diào)用之時閉包外部的變量a的內(nèi)存地址:  494384224
函數(shù)inner調(diào)用之后閉包內(nèi)部變量a的內(nèi)存地址:  494384256
函數(shù)inner調(diào)用之后,閉包外部的變量a的內(nèi)存地址:  494384224
函數(shù)outer執(zhí)行完畢,全局變量a的內(nèi)存地址:  494384256

那怎么辦呢?使用nonlocal關(guān)鍵字!它可以修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量。將global a改成nonlocal a,代碼這里我就不重復(fù)貼了,運行后查看結(jié)果,可以看到我們真的引用了outer函數(shù)的a變量。

函數(shù)outer調(diào)用之前全局變量a的內(nèi)存地址:  497726528
函數(shù)outer調(diào)用之時閉包外部的變量a的內(nèi)存地址:  497726560
函數(shù)inner調(diào)用之后閉包內(nèi)部變量a的內(nèi)存地址:  497726592
函數(shù)inner調(diào)用之后,閉包外部的變量a的內(nèi)存地址:  497726592
函數(shù)outer執(zhí)行完畢,全局變量a的內(nèi)存地址:  497726528

到此,關(guān)于“Python函數(shù)如何自定義”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

新聞名稱:Python函數(shù)如何自定義
轉(zhuǎn)載來源:http://jinyejixie.com/article10/iisggo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)、面包屑導(dǎo)航定制網(wǎng)站、關(guān)鍵詞優(yōu)化、微信公眾號響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)
南和县| 银川市| 定日县| 庐江县| 大洼县| 临桂县| 崇信县| 水城县| 武穴市| 利川市| 白山市| 交城县| 青河县| 楚雄市| 登封市| 城市| 皋兰县| 和田市| 宁津县| 靖江市| 石屏县| 绥滨县| 荔波县| 于田县| 峡江县| 合川市| 清水河县| 昌江| 垦利县| 尼玛县| 潼关县| 康保县| 万安县| 内乡县| 蕲春县| 靖西县| 西宁市| 松潘县| 威信县| 泌阳县| 博野县|