python-函數(二)

來源:互聯網
上載者:User

標籤:com   注意   處理   on()   字串   hello   images   作用   記憶體配置   

Python中的函數(二)

  在上一篇文章中提到了Python中函數的定義和使用,在這篇文章裡我們來討論下關於函數的一些更深的話題。在學習C語言函數的時候,遇到的問題主要有形參實參的區別、參數的傳遞和改變、變數的範圍。同樣在Python中,關於對函數的理解和使用也存在這些問題。下面來逐一講解。

一.函數形參和實參的區別
  形參全稱是形式參數,在用def關鍵字定義函數時函數名後面括弧裡的變數稱作為形式參數。
   實參全稱為實際參數,在調用函數時提供的值或者變數稱作為實際參數。

舉個例子:

def add(a,b):       //這裡的a和b就是形參    return a+badd(1,2)     //這裡的1和2是實參
x=2y=3add(x,y) //這裡的x和y是實參

 

二.參數的傳遞和改變
  下面我們來探討一下Python中的【函數參數的傳遞】問題。

  首先在討論這個問題之前,我們需要明確一點就是在Python中一切皆對象,變數中存放的是對象的引用。這個確實有點難以理解,“一切皆對象”?對,在Python中確實是這樣,包括我們之前經常用到的字串常量,整型常量都是對象。不信的話可以驗證一下:

例1、

print id(2)
x=2print id(x)

y=‘hello‘print id(y)

 //從結果可以看出,id(2)和id(x)的值是一樣的,id(‘hello‘)和id(y)的值也是一樣的。
  在Python中一切皆對象,像2,‘hello‘這樣的值都是對象,只不過2是一個整型對象,而‘hello‘是一個字串對象。
  上面的x=2,在Python中實際的處理過程是這樣的:先申請一段記憶體配置給一個整型對象來儲存整型值2,然後讓變數x去指向這個對象,實際上就是指向這段記憶體(這裡有點和C語言中的指標類似)。而id(2)和id(x)的結果一樣,說明id函數在作用於變數時,其返回的是變數指向的對象的地址。因為變數也是對象,所以在這裡可以將x看成是對象2的一個引用。

例2、

x=2print id(x)
y=2print id(y)
s=‘hello‘print id(s)t=sprint id(t)

其運行結果為:
 
從運行結果可以看到id(x)和id(y)的結果是相同的,id(s)和id(t)的結果也是相同的。這說明x和y指向的是同一對象,而t和s也是指向的同一對象。x=2這句讓變數x指向了int類型的對象2,而y=2這句執行時,並不重新為2分配空間,而是讓y直接指向了已經存在的int類型的對象2。這個很好理解,因為本身只是想給y賦一個值2,而在記憶體中已經存在了這樣一個int類型對象2,所以就直接讓y指向了已經存在的對象。這樣一來不僅能達到目的,還能節約記憶體空間。t=s這句變數互相賦值,也相當於是讓t指向了已經存在的字串類型的對象‘hello‘(這個原理和C語言中指標的互相賦值有點類似)。

  看這幅圖就理解了:
  

例3、

x=2print id(2)print id(x)
x=3print id(3)print id(x)
L=[1,2,3]M=Lprint id(L)print id(M)print id(L[2])
L[0]=2print id(L)print M

運行結果為:
 
  下面來分析一下這個結果,兩次的id(x)的值不同,這個可能讓人有點難以理解。注意,在Python中,單一元素的對象是不允許更改的,比如整型資料、字串、浮點數等。x=3這句的執行過程並不是先擷取x原來指向的對象的地址,再把記憶體中的值更改為3,而是新申請一段記憶體來儲存物件3,再讓x去指向對象3,所以兩次id(x)的值不同。然而為何改變了L中的某個子項目的值後,id(L)的值沒有發生改變?在Python中,複雜元素的對象是允許更改的,比如列表、字典、元組等。Python中變數儲存的是對象的引用,對於列表,其id()值返回的是列表第一個子項目L[0]的儲存地址。就像上面的例子,L=[1,2,3],這裡的L有三個子項目L[0],L[1],L[2],L[0]、L[1]、L[2]分別指向對象1、2、3,id(L)值和對象3的儲存地址相同,看下面這個圖就明白了:
      
//因為L和M指向的是同一對象,所以在更改了L中子項目的值後,M也相應改變了,但是id(L)值並沒有改變,因為這句L[0]=2隻是讓L[0]重新指向了對象2,而L[0]本身的儲存地址並沒有發生改變,所以id(L)的值沒有改變( id(L)的值實際等於L[0]本身的儲存地址)。如下:
       

 

  下面就來討論一下【函數的參數傳遞和改變】這個問題。
  在Python中參數傳遞採用的是值傳遞,這個和C語言有點類似。

例1、

def modify1(m,K):    m=2    K=[4,5,6]    return    def modify2(m,K):    m=2    K[0]=0    returnn=100L=[1,2,3]
modify1(n,L)print nprint L
modify2(n,L)print nprint L

  程式運行結果為:    

  

 從結果可以看出,執行modify1( )之後,n和L都沒有發生任何改變;執行modify2( )後,n還是沒有改變,L發生了改變。因為在Python中參數傳遞採用的是值傳遞方式,在執行函數modify1時,先擷取n和L的id( )值,然後為形參m和K分配空間,讓m和K分別指向對象100和對象[1,2,3]。m=2這句讓m重新指向對象2,而K=[4,5,6]這句讓K重新指向對象[4,5,6]。這種改變並不會影響到實參n和L,所以在執行modify1之後,n和L沒有發生任何改變;在執行函數modify2時,同理,讓m和K分別指向對象2和對象[1,2,3],然而K[0]=0讓K[0]重新指向了對象0(注意這裡K和L指向的是同一段記憶體),所以對K指向的記憶體資料進行的任何改變也會影響到L,因此在執行modify2後,L發生了改變。



三.變數的範圍
  在Python中,也存在範圍這個問題。在Python中,會為每個層次產生一個符號表,裡層能調用外層中的變數,而外層不能調用裡層中的變數,並且當外層和裡層有同名變數時,外層變數會被裡層變數屏蔽掉。
舉個例子:

def function():    x=2    count=2    while count>0:        x=3        print x        count=count-1
function()

  在函數function中,while迴圈外面和while迴圈裡面都有變數x,此時,while迴圈外面的變數x會被屏蔽掉。注意在函數內部定義的變數範圍都僅限於函數內部,在函數外部是不能夠調用的,一般稱這種變數為局部變數。

  還有一種變數叫做全域變數,它是在函數外部定義的,範圍是整個檔案。全域變數可以直接在函數裡面應用,但是如果要在函數內部改變全域變數,必須使用global關鍵字進行聲明。

x=2def fun1():    print x    def fun2():    global x    x=3    print xfun1()fun2()print x



python-函數(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.