當前位置:首頁 » 編程語言 » python參數引用

python參數引用

發布時間: 2023-06-03 18:34:55

1. python 定義的函數的參數傳遞是怎麼樣的

Python變數沒有賦值,都是引用。

大多語言,是聲明一個變數,給它分配一個空間保存一個值,也就是賦值。

Python則是給一個值分配一個空間,變數=這個值,只是這個變數引用了這個值的地址,也就是說,a=1,b=1,c=1,Python只分配了一個空間,保存這個值1。 a,b,c都引用了這個地址。

2. python腳本入參的單、雙引號

Linux的shell中存在一些特殊字元(保留字),我們將這些具有一些特殊功能的字元叫做meta(元字元),還有一些普通的,沒有特殊功能的字元我們叫做literal(文字)。bash中,常使用的引用有如下三種方法:

    1、單引號:單引號中的所有meta均被當作普通字元使用。

    2、雙引號:在雙引號中的大部分meta都被當作普通字元,但某些字元的功能保留(如$)。

    3、反斜線:只有緊接在反斜線(跳脫字元)之後的單一meta才被當作普通字元。

Windows的cmd下,同樣也有類似的概念。單引號和雙引號有時候沒有區別(可以使用任意一個),有時候只能用特定的一個。

這篇文章主要記錄python腳本入參帶有&&符號時,在Linux和Windows平台的不同表現。

編寫python腳本quote.py,內容如下:

$ cat quote.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

print(sys.argv[1])

1、參數不使用引號

$ python quote.py whoami&&whoami

whoami

sunday

可以看出,第一個whoami被當作入參傳給腳本,第二個whoami當作bash命令,在終端執行。

2、參數使用單引號

$ python quote.py 'whoami&&whoami'

whoami&&whoami

可以看出,&&被當作普通字元,whoami&&whoami作為參數傳給了腳本。

3、參數使用雙引號

$ python quote.py "whoami&&whoami"

whoami&&whoami

可以看出,&&被當作普通字元,whoami&&whoami作為參數傳給了腳本。

在Windows執行腳本,用戶為winsunday:

1、參數不使用引號

C:\test>python quote.py whoami&&whoami

whoami

winsunday

可以看出,第一個whoami被當作入參傳給腳本,第二個whoami當作CMD命令,在終端執行。

2、參數使用單引號

C:\test>python quote.py 'whoami&&whoami'

'whoami

'whoami'' 不是內部或外部命令,也不是可運行的程序

或批處理文件。

可以看出,單引號被當作普通字元,&&對命令進行了分割,'whoami作為第一個參數被傳給腳本;whoami'被認為是一個命令進行執行(報錯了)。

3、參數使用雙引號

C:\test>python quote.py "whoami&&whoami"

whoami&&whoami

可以看出,雙引號時&&被當作普通字元,whoami&&whoami作為整體被傳給腳本。

3. Python 的函數是怎麼傳遞參數的

對象vs變數
在python中,類型屬於對象,變數是沒有類型的,這正是python的語言特性,也是吸引著很多pythoner的一點。所有的變數都可以理解是內存中一個對象的「引用」,或者,也可以看似c中void*的感覺。所以,希望大家在看到一個python變數的時候,把變數和真正的內存對象分開。
類型是屬於對象的,而不是變數。
這樣,很多問題就容易思考了。
例如:

對象vs變數
12
nfoo = 1 #一個指向int數據類型的nfoo(再次提醒,nfoo沒有類型)lstFoo = [1] #一個指向list類型的lstFoo,這個list中包含一個整數1

可更改(mutable)與不可更改(immutable)對象
對應於上一個概念,就必須引出另了另一概念,這就是可更改(mutable)對象與不可更改(immutable)對象。
對於python比較熟悉的人們都應該了解這個事實,在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是可以修改的對象。那麼,這些所謂的可改變和不可改變影響著什麼呢?
可更改vs不可更改
12345
nfoo = 1nfoo = 2lstFoo = [1]lstFoo[0] = 2

代碼第2行中,內存中原始的1對象因為不能改變,於是被「拋棄」,另nfoo指向一個新的int對象,其值為2
代碼第5行中,更改list中第一個元素的值,因為list是可改變的,所以,第一個元素變更為2。其實應該說,lstFoo指向一個包含一個對象的數組。賦值所發生的事情,是有一個新int對象被指定給lstFoo所指向的數組對象的第一個元素,但是對於lstFoo本身來說,所指向的數組對象並沒有變化,只是數組對象的內容發生變化了。這個看似void*的變數所指向的對象仍舊是剛剛的那個有一個int對象的list。
如下圖所示:

Python的函數參數傳遞:傳值?引用?
對於變數(與對象相對的概念),其實,python函數參數傳遞可以理解為就是變數傳值操作,用C++的方式理解,就是對void*賦值。如果這個變數的值不變,我們看似就是引用,如果這個變數的值改變,我們看著像是在賦值。有點暈是吧,我們仍舊據個例子。
不可變對象參數調用
12345
def ChangeInt( a ): a = 10nfoo = 2 ChangeInt(nfoo)print nfoo #結果是2

這時發生了什麼,有一個int對象2,和指向它的變數nfoo,當傳遞給ChangeInt的時候,按照傳值的方式,復制了變數nfoo的值,這樣,a就是nfoo指向同一個Int對象了,函數中a=10的時候,發生什麼?(還記得我上面講到的那些概念么),int是不能更改的對象,於是,做了一個新的int對象,另a指向它(但是此時,被變數nfoo指向的對象,沒有發生變化),於是在外面的感覺就是函數沒有改變nfoo的值,看起來像C++中的傳值方式。
可變對象參數調用
12345
def ChangeList( a ): a[0] = 10lstFoo = [2]ChangeList(lstFoo )print nfoo #結果是[10]

當傳遞給ChangeList的時候,變數仍舊按照「傳值」的方式,復制了變數lstFoo 的值,於是a和lstFoo 指向同一個對象,但是,list是可以改變的對象,對a[0]的操作,就是對lstFoo指向的對象的內容的操作,於是,這時的a[0] = 10,就是更改了lstFoo 指向的對象的第一個元素,所以,再次輸出lstFoo 時,顯示[10],內容被改變了,看起來,像C++中的按引用傳遞。

4. python怎麼傳參

Python函數參數傳遞機制問題在本質上是調用函數(過程)和被調用函數(過程)在調用發生時進行通信的方法問題。基本的參數傳遞
機制有兩種:值傳遞和引用傳遞。值傳遞(passl-by-value)過程中,被調函數的形式參數作為被調函數的局部變數處理,即在堆棧中開
辟了內存空間以存放由主調函數放進來的實參的值,從而成為了實參的一個副本。值傳遞的特點是被調函數對形式參數的任何操作都是作
為局部變數進行,不會影響主調函數的實參變數的值。(推薦學習:Python視頻教程)
引用傳遞(pass-by-reference)過程中,被調函數的形式參數雖然也作為局部變數在堆棧中開辟了內存空間,但是這時存放的是由主調函
數放進來的實參變數的地址。被調函數對形參的任何操作都被處理成間接定址,即通過堆棧中存放的地址訪問主調函數中的實參變數。正
因為如此,被調函數對形參做的任何操作都影響了主調函數中的實參變數。

5. Python的函數和參數

parameter 是函數定義的參數形式
argument 是函數調用時傳入的參數實體。

對於函數調用的傳參模式,一般有兩種:

此外,

也是關鍵字傳參

python的函數參數定義一般來說有五種: 位置和關鍵字參數混合 僅位置參數 僅關鍵字參數 可變位置參數 可變關鍵字參數 。其中僅位置參數的方式僅僅是一個概念,python語法中暫時沒有這樣的設計。
通常我們見到的函數是位置和關鍵字混合的方式。

既可以用關鍵字又可以用位置調用

這種方式的定義只能使用關鍵字傳參的模式

f(*some_list) 與 f(arg1, arg2, ...) (其中some_list = [arg1, arg2, ...])是等價的

網路模塊request的request方法的設計
多數的可選參數被設計成可變關鍵字參數

有多種方法能夠為函數定義輸出:

非常晦澀

如果使用可變對象作為函數的默認參數,會導致默認參數在所有的函數調用中被共享。
例子1:

addItem方法的data設計了一個默認參數,使用不當會造成默認參數被共享。
python裡面,函數的默認參數被存在__default__屬性中,這是一個元組類型
例子2:

在例子1中,默認參數是一個列表,它是mutable的數據類型,當它寫進 __defauts__屬性中時,函數addItem的操作並不會改變它的id,相當於 __defauts__只是保存了data的引用,對於它的內存數據並不關心,每次調用addItem,都可以修改 addItem.__defauts__中的數據,它是一個共享數據。
如果默認參數是一個imutable類型,情況將會不一樣,你無法改變默認參數第一次存入的值。

例子1中,連續調用addItem('world') 的結果會是

而不是期望的

6. python中變數的引用、可變和不可變類型、局部變數和全局變數

變數的引用

變數和數據都是保存在內存中的

變數和數據是分開存儲

數據保存在內存中某個位置,通過地址來標記

變數保存的是數據的地址,通過地址可以找到數據在內存空間的位置

把變數保存數據地址的過程稱為引用


變數的重新賦值修改的是變數中引用數據的內存地址

變數之間的賦值實際是引用的傳遞

函數參數的傳遞,本質也是引用的傳遞

函數的返回值本身也是引用的傳遞


可變和不可變類型

不可變類型,內存中的數據不允許被修改:數字類型(int,bool,float,complex,long(2,x)、字元串、元組(tuple)

可變類型,內存中的數據可以被修改:列表list、字典dict

無論是可變還是不可變數據類型,通過賦值語句,都會改變變數的引用


Hash函數只能接收不可變數據類型,字典的鍵也只能是不可變數據類型,字典的value值可以是任意數據類型


局部變數

1.在函數內部定義的變數就是局部變數(作用范圍只能是當前函數內部)

2.在函數外部無法直接訪問局部變數

3.不同的函數中可以定義同名的局部變數

4.局部變數的生命周期:從定義變數時開始,到函數運行結束

全局變數

1.在所有函數外邊定義的變數就是全局變數

2.讓所有函數都能訪問到,可以作為函數通信的橋梁

3.一般情況下,為了和普通變數的區別,需要加上g_或gl_前綴

4.全局變數一般放在所有函數的最上面

5.在函數內部修改全局變數,必須要加上global關鍵字,如果不加global只是定義了一個同名的局部變數


函數的多個返回值

7. Python函數的參數類型

Python函數的參數類型主要包括必選參數、可選參數、可變參數、位置參數和關鍵字參數,本文介紹一下他們的定義以及可變數據類型參數傳遞需要注意的地方。

必選參數(Required arguments)是必須輸入的參數,比如下面的代碼,必須輸入2個參數,否則就會報錯:

其實上面例子中的參數 num1和num2也屬於關鍵字參數,比如可以通過如下方式調用:

執行結果:

可選參數(Optional arguments)可以不用傳入函數,有一個默認值,如果沒有傳入會使用默認值,不會報錯。

位置參數(positional arguments)根據其在函數定義中的位置調用,下面是pow()函數的幫助信息:

x,y,z三個參數的的順序是固定的,並且不能使用關鍵字:

輸出:

在上面的pow()函數幫助信息中可以看到位置參數後面加了一個反斜杠 / ,這是python內置函數的語法定義,Python開發人員不能在python3.8版本之前的代碼中使用此語法。但python3.0到3.7版本可以使用如下方式定義位置參數:

星號前面的參數為位置參數或者關鍵字參數,星號後面是強制關鍵字參數,具體介紹見強制關鍵字參數。

python3.8版本引入了強制位置參數(Positional-Only Parameters),也就是我們可以使用反斜杠 / 語法來定義位置參數了,可以寫成如下形式:

來看下面的例子:

python3.8運行:

不能使用關鍵字參數形式賦值了。

可變參數 (varargs argument) 就是傳入的參數個數是可變的,可以是0-n個,使用星號( * )將輸入參數自動組裝為一個元組(tuple):

執行結果:

關鍵字參數(keyword argument)允許將任意個含參數名的參數導入到python函數中,使用雙星號( ** ),在函數內部自動組裝為一個字典。

執行結果:

上面介紹的參數可以混合使用:

結果:

注意:由於傳入的參數個數不定,所以當與普通參數一同使用時,必須把帶星號的參數放在最後。

強制關鍵字參數(Keyword-Only Arguments)是python3引入的特性,可參考:https://www.python.org/dev/peps/pep-3102/。 使用一個星號隔開:

在位置參數一節介紹過星號前面的參數可以是位置參數和關鍵字參數。星號後面的參數都是強制關鍵字參數,必須以指定參數名的方式傳參,如果強制關鍵字參數沒有設置默認參數,調用函數時必須傳參。

執行結果:

也可以在可變參數後面命名關鍵字參數,這樣就不需要星號分隔符了:

執行結果:

在Python對象及內存管理機制中介紹了python中的參數傳遞屬於對象的 引用傳遞 (pass by object reference),在編寫函數的時候需要特別注意。

先來看個例子:

執行結果:

l1 和 l2指向相同的地址,由於列表可變,l1改變時,l2也跟著變了。

接著看下面的例子:

結果:

l1沒有變化!為什麼不是[1, 2, 3, 4]呢?

l = l + [4]表示創建一個「末尾加入元素 4「的新列表,並讓 l 指向這個新的對象,l1沒有進行任何操作,因此 l1 的值不變。如果要改變l1的值,需要加一個返回值:

結果:

下面的代碼執行結果又是什麼呢?

執行結果:

和第一個例子一樣,l1 和 l2指向相同的地址,所以會一起改變。這個問題怎麼解決呢?

可以使用下面的方式:

也可以使用淺拷貝或者深度拷貝,具體使用方法可參考Python對象及內存管理機制。這個問題在Python編程時需要特別注意。

本文主要介紹了python函數的幾種參數類型:必選參數、可選參數、可變參數、位置參數、強制位置參數、關鍵字參數、強制關鍵字參數,注意他們不是完全獨立的,比如必選參數、可選參數也可以是關鍵字參數,位置參數可以是必選參數或者可選參數。

另外,python中的參數傳遞屬於對象的 引用傳遞 ,在對可變數據類型進行參數傳遞時需要特別注意,如有必要,使用python的拷貝方法。

參考文檔:

--THE END--

8. python函數的參數傳遞是傳值還是傳引用

那要看數據類型了,int,float,str這種就是傳值,list,dict,類的實例,自定義對象都是穿引用。

下面是示例代碼:

defchange(int1,float1,str1,dict1,obj1,list1):
int1+=1
float1+=1
str1+='changed'
dict1['none_exist_key']='none_exist_value'
obj1=None
list1.append('change')
classobj:
pass
int1=0
float1=0.0
str1='origin'
dict1={'key':'value'}
obj1=obj()
list1=['only_element']
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)
change(int1,float1,str1,dict1,obj1,list1)
print('afterchange')
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)

不明白可追問

熱點內容
linux刻錄iso 發布:2025-05-18 00:16:15 瀏覽:661
php動態參數 發布:2025-05-18 00:12:05 瀏覽:424
安卓應用上傳 發布:2025-05-18 00:11:57 瀏覽:802
數對的演算法 發布:2025-05-18 00:11:02 瀏覽:381
linuxwhile 發布:2025-05-18 00:10:08 瀏覽:143
xpftp外網 發布:2025-05-17 23:58:11 瀏覽:385
如何評價一個伺服器的性能 發布:2025-05-17 23:40:53 瀏覽:270
淘寶客適合什麼伺服器 發布:2025-05-17 23:39:26 瀏覽:613
python循環文件 發布:2025-05-17 23:39:22 瀏覽:828
androidstudio更新 發布:2025-05-17 23:38:22 瀏覽:643