導航:首頁 > 編程語言 > python替換作用域的參數

python替換作用域的參數

發布時間:2023-07-20 15:26:04

❶ 深入探究python中變數的拷貝和作用域問題

這篇文章主要介紹了Python中變數的拷貝和作用域問題,包括一些賦值、引用問題,以及相關函數在Python2和3版本之間的不同,需要的朋友可以參考下

python
中賦值語句總是建立對象的引用值,而不是復制對象。因此,python
變數更像是指針,而不是數據存儲區域,
這點和大多數
OO
語言類似吧,比如
C++、java

~
1、先來看個問題吧:
在Python中,令values=[0,1,2];values[1]=values,為何結果是[0,[...],2]?
?
1
2
3
4
>>>
values
=
[0,
1,
2]
>>>
values[1]
=
values
>>>
values
[0,
[...],
2]
我預想應當是
?
1
[0,
[0,
1,
2],
2]
但結果卻為何要賦值無限次?
可以說
Python
沒有賦值,只有引用。你這樣相當於創建了一個引用自身的結構,所以導致了無限循環。為了理解這個問題,有個基本概念需要搞清楚。
Python
沒有「變數」,我們平時所說的變數其實只是「標簽」,是引用。
執行
?
1
values
=
[0,
1,
2]
的時候,Python
做的事情是首先創建一個列表對象
[0,
1,
2],然後給它貼上名為
values
的標簽。如果隨後又執行
?
1
values
=
[3,
4,
5]
的話,Python
做的事情是創建另一個列表對象
[3,
4,
5],然後把剛才那張名為
values
的標簽從前面的
[0,
1,
2]
對象上撕下來,重新貼到
[3,
4,
5]
這個對象上。
至始至終,並沒有一個叫做
values
的列表對象容器存在,Python
也沒有把任何對象的值復制進
values
去。過程如圖所示:
執行
?
1
values[1]
=
values
的時候,Python
做的事情則是把
values
這個標簽所引用的列表對象的第二個元素指向
values
所引用的列表對象本身。執行完畢後,values
標簽還是指向原來那個對象,只不過那個對象的結構發生了變化,從之前的列表
[0,
1,
2]
變成了
[0,
?,
2],而這個
?
則是指向那個對象本身的一個引用。如圖所示:
要達到你所需要的效果,即得到
[0,
[0,
1,
2],
2]
這個對象,你不能直接將
values[1]
指向
values
引用的對象本身,而是需要吧
[0,
1,
2]
這個對象「復制」一遍,得到一個新對象,再將
values[1]
指向這個復制後的對象。Python
裡面復制對象的操作因對象類型而異,復制列表
values
的操作是
values[:]
#生成對象的拷貝或者是復制序列,不再是引用和共享變數,但此法只能頂層復制
所以你需要執行
?
1
values[1]
=
values[:]
Python
做的事情是,先
dereference
得到
values
所指向的對象
[0,
1,
2],然後執行
[0,
1,
2][:]
復制操作得到一個新的對象,內容也是
[0,
1,
2],然後將
values
所指向的列表對象的第二個元素指向這個復制二來的列表對象,最終
values
指向的對象是
[0,
[0,
1,
2],
2]。過程如圖所示:
往更深處說,values[:]
復制操作是所謂的「淺復制」(shallow
),當列表對象有嵌套的時候也會產生出乎意料的錯誤,比如
?
1
2
3
4
a
=
[0,
[1,
2],
3]
b
=
a[:]
a[0]
=
8
a[1][1]
=
9
問:此時
a

b
分別是多少?
正確答案是
a

[8,
[1,
9],
3],b

[0,
[1,
9],
3]。發現沒?b
的第二個元素也被改變了。想想是為什麼?不明白的話看下圖
正確的復制嵌套元素的方法是進行「深復制」(deep
),方法是
?
1
2
3
4
5
6
import


a
=
[0,
[1,
2],
3]
b
=
.deep(a)
a[0]
=
8
a[1][1]
=
9
2、引用
VS
拷貝:
(1)沒有限制條件的分片表達式(L[:])能夠復制序列,但此法只能淺層復制。
(2)字典

方法,D.()
能夠復制字典,但此法只能淺層復制
(3)有些內置函數,例如
list,能夠生成拷貝
list(L)
(4)
標准庫模塊能夠生成完整拷貝:deep
本質上是遞歸

(5)對於不可變對象和可變對象來說,淺復制都是復制的引用,只是因為復制不變對象和復制不變對象的引用是等效的(因為對象不可變,當改變時會新建對象重新賦值)。所以看起來淺復制只復制不可變對象(整數,實數,字元串等),對於可變對象,淺復制其實是創建了一個對於該對象的引用,也就是說只是給同一個對象貼上了另一個標簽而已。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
L
=
[1,
2,
3]
D
=
{'a':1,
'b':2}
A
=
L[:]
B
=
D.()
print
"L,
D"
print
L,
D
print
"A,
B"
print
A,
B
print
"--------------------"
A[1]
=
'NI'
B['c']
=
'spam'
print
"L,
D"
print
L,
D
print
"A,
B"
print
A,
B

L,
D
[1,
2,
3]
{'a':
1,
'b':
2}
A,
B
[1,
2,
3]
{'a':
1,
'b':
2}
--------------------
L,
D
[1,
2,
3]
{'a':
1,
'b':
2}
A,
B
[1,
'NI',
3]
{'a':
1,
'c':
'spam',
'b':
2}
3、增強賦值以及共享引用:
x
=
x
+
y,x
出現兩次,必須執行兩次,性能不好,合並必須新建對象
x,然後復制兩個列表合並
屬於復制/拷貝
x
+=
y,x
只出現一次,也只會計算一次,性能好,不生成新對象,只在內存塊末尾增加元素。

x、y
為list時,
+=
會自動調用
extend
方法進行合並運算,in-place
change。
屬於共享引用
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
L
=
[1,
2]
M
=
L
L
=
L
+
[3,
4]
print
L,
M
print
"-------------------"
L
=
[1,
2]
M
=
L
L
+=
[3,
4]
print
L,
M

[1,
2,
3,
4]
[1,
2]
-------------------
[1,
2,
3,
4]
[1,
2,
3,
4]
4、python
從2.x
到3.x,語句變函數引發的變數作用域問題
先看段代碼:
?
1
2
3
4
5
6
7
8
9
def
test():
a
=
False
exec
("a
=
True")
print
("a
=
",
a)
test()

b
=
False
exec
("b
=
True")
print
("b
=
",
b)

python
2.x

3.x

你會發現他們的結果不一樣:
?
1
2
3
4
5
6
7
2.x:
a
=
True
b
=
True

3.x:
a
=
False
b
=
True
這是為什麼呢?
因為
3.x

exec
由語句變成函數了,而在函數中變數默認都是局部的,也就是說
你所見到的兩個
a,是兩個不同的變數,分別處於不同的命名空間中,而不會沖突。
具體參考
《learning
python》P331-P332
知道原因了,我們可以這么改改:
?
1
2
3
4
5
6
7
8
9
10
11
12
def
test():
a
=
False
ldict
=
locals()
exec("a=True",globals(),ldict)
a
=
ldict['a']
print(a)

test()

b
=
False
exec("b
=
True",
globals())
print("b
=
",
b)
這個問題在
stackoverflow
上已經有人問了,而且
python
官方也有人報了
bug。。。
具體鏈接在下面:
http://stackoverflow.com/questions/7668724/variables-declared-in-execed-code-dont-become-local-in-python-3-documentatio
http://bugs.python.org/issue4831
http://stackoverflow.com/questions/1463306/how-does-exec-work-with-locals

❷ 數據分析員用python做數據分析是怎麼回事,需要用到python中的那些內容,具體是怎麼操作的

大數據!大數據!其實是離不開數據二字,但是總體來講,自己之前對數據的認知是不太夠的,更多是在關注技術的提升上。換句話講,自己是在做技術,這些技術處理的是數據,而不能算是自己是在做數據的。大規模數據的處理是一個非常大的課題,但是這一點更偏向於是搞技術的。

與數據分析相關的Python庫很多,比如Numpy、pandas、matplotlib、scipy等,數據分析的操作包括數據的導入和導出、數據篩選、數據描述、數據處理、統計分析、可視化等等。接下來我們看一下如何利用Python完成數據的分析。
生成數據表
常見的生成方法有兩種,第一種是導入外部數據,第二種是直接寫入數據,Python支持從多種類型的數據導入。在開始使用Python進行數據導入前需要先導入pandas庫,為了方便起見,我們也同時導入Numpy庫。代碼是最簡模式,裡面有很多可選參數設置,例如列名稱、索引列、數據格式等等。
檢查數據表
Python中使用shape函數來查看數據表的維度,也就是行數和列數。你可以使用info函數查看數據表的整體信息,使用dtypes函數來返回數據格式。Isnull是Python中檢驗空值的函數,你可以對整個數據表進行檢查,也可以單獨對某一列進行空值檢查,返回的結果是邏輯值,包含空值返回True,不包含則返回False。使用unique函數查看唯一值,使用Values函數用來查看數據表中的數值。
數據表清洗
Python中處理空值的方法比較靈活,可以使用Dropna函數用來刪除數據表中包含空值的數據,也可以使用fillna函數對空值進行填充。Python中dtype是查看數據格式的函數,與之對應的是astype函數,用來更改數據格式,Rename是更改列名稱的函數,drop_plicates函數刪除重復值,replace函數實現數據替換。
數據預處理
數據預處理是對清洗完的數據進行整理以便後期的統計和分析工作,主要包括數據表的合並、排序、數值分列、數據分組及標記等工作。在Python中可以使用merge函數對兩個數據表進行合並,合並的方式為inner,此外還有left、right和outer方式。使用ort_values函數和sort_index函數完成排序,使用where函數完成數據分組,使用split函數實現分列。
數據提取
主要是使用三個函數:loc、iloc和ix,其中loc函數按標簽值進行提取,iloc按位置進行提取,ix可以同時按標簽和位置進行提取。除了按標簽和位置提起數據以外,還可以按具體的條件進行數據,比如使用loc和isin兩個函數配合使用,按指定條件對數據進行提取。
數據篩選匯總
Python中使用loc函數配合篩選條件來完成篩選功能,配合sum和 count函數還能實現excel中sumif和countif函數的功能。Python中使用的主要函數是groupby和pivot_table。groupby是進行分類匯總的函數,使用方法很簡單,制定要分組的列名稱就可以,也可以同時制定多個列名稱,groupby 按列名稱出現的順序進行分組。

❸ Python 中作用域與命名空間的問題

i=2這一句是定義了一個局部變數i,並賦值為2;這個時候全局作用域的i會被屏蔽,所以全局變數i是沒有被修改的所以結果是1;


訪問全局變數時可以直接訪問,但是修改全局作用域的時候一定要在賦值之前,進行如下聲明:

deff():

globali


i=2


因為python里賦值語句和聲明變數是一個體的,所以需要global來告訴解釋器i是全局變數,接下來的i=2才能被當作是賦值

------------------追答---------------------

同一個代碼塊(作用域)里, 同一個變數的作用域只能是同一種或者說同一個變數只能來自同一個作用域, 不能是一會是局部變數然後又變成全局變數;

i = i + 1

首先前面的'i='表明了i是一個局部變數(沒有global聲明, 創建局部變數), 然後後面的'i+1'里的i自然也是局部變數(同一個函數下同一個變數,i已經是局部變數了, 不能再當作全局變數去用), 那麼自然會報錯, i在使用前未聲明

i += 1

報錯就更明顯了, 沒有global聲明 那麼再修改變數i的時候, 自然是當作局部變數, 使用前未聲明

變數的查找順序遵循 LEGB 可以自己網路

關於作用域給你再寫個簡單的示例, 你對照著理解一下

❹ Python其實很簡單 第十二章 函數與變數的作用域

在前面已經多次提到函數這個概念,之所以沒有解釋什麼是函數,是因為程序中的函數和數學中的函數差不多,如input()、range()等都是函數,這些都是Python的標准函數,直接使用就可以了。根據需要,用戶也可以自定義函數。

12.1 函數

函數的結構:

def 函數名(參數):

函數體

return 返回值

例如:數學中的函數f(x)=2x+5在Python中可以定義如下:

def f(x):

y=2*x+5

return(y)

如果x取值為3,可以使用如下語句調用函數:

f(3)

下面給出完整的程序代碼:

def f(x):

y=2*x+5

return(y)

res=f(3)

print(res)

運行結果:11

如上例中的x是函數f(x)的參數,有時也被稱為形式參數(簡稱形參),在函數被調用時,x被具體的值3替換y就是函數的返回值,這個值3也被稱為實際參數(簡稱實參)。

上例中的y是函數f(x)的返回值。並不是所有的函數都有參數和返回值。如下面的函數:

def func():

print('此為無參數傳遞、無返回值的函數')

func()

輸出結果:此為無參數傳遞、無返回值的函數

可以看出,該函數func()無參數,故調用時不用賦給參數值。

函數也可以有多個參數,如f(x,y)=x²+y²,可用Python語言定義如下:

def f(x,y):

z=x**2+y**2

return z

print(f(2,3)) #調用函數f(x,y)

輸出結果:13

也可以通過直接給參數列表中的參數賦值的方法,為參數添加默認值,如果用戶賦予參數值,則按照用戶賦值執行,否則使用默認值。例如:

def f(x,y=3):

z=x**2+y**2

return z

若調用時參數列表為(2,1),即x賦值為2,y賦值為1:

print(f(2,1))

輸出結果為:5

若調用時參數列表為(2),即x賦值為2,y賦值省缺,則y使用默認值:

print(f(2))

輸出結果為:13

回調函數,又稱函數回調,是將函數作為另一函數的參數。

例如:

def func(fun,m,n):

fun(m,n)

def f_add(m,n):

print('m+n=',m+n)

def f_mult(m,n):

print('m*n=',m*n)

func(f_add,2,3)

func(f_mult,2,3)

輸出結果:

m+n= 5

m*n= 6

在f_add(m,n)和f_mult(m,n)被定義前,func(fun,m,n)中的fun(m,n)就已經調用了這兩個函數,即「先調用後定義」,這也是回調函數的特點。

如果無法預知參數的個數,可以在參數前面加上*號,這種參數實際上對應元組類型。譬如,參會的人數事先不能確定,只能根據與會人員名單輸入:

def func(*names):

print('今天與會人員有:')

for name in names:

print(name)

func('張小兵','陳曉梅','李大海','王長江')

運行後,輸出結果為:

今天與會人員有:

張小兵

陳曉梅

李大海

王長江

參數為字典類型,需要在參數前面加上**號。

def func(**kwargs):

for i in kwargs:

print(i,kwargs[i])

func(a='a1',b='b1',c='c1')

輸出結果為:

a a1

b b1

c c1

一個有趣的實例:

def func(x,y,z,*args,**kwargs):

print(x,y,z)

print(args)

print(kwargs)


func('a','b','c','Python','is easy',py='python',j='java',ph='php')

輸出結果:

a b c # 前三個實參賦給前三個形參

('Python', 'is easy') # *args接收元組數據

{'py': 'python', 'j': 'java', 'ph': 'php'} # **kwargs接收字典數據

12.2 變數的作用域

變數的作用域即變數的有效范圍,可分為全局變數和局部變數。

局部變數

在函數中定義的變數就是局部變數,局部變數的作用域僅限於函數內部使用。

全局變數

在主程序中定義的變數就是全局變數,但在函數中用關鍵字global修飾的變數也可以當做全局變數來使用。

全局變數的作用域是整個程序,也就是說,全局變數可以在整個程序中可以訪問。

下面通過實例去討論:

程序1:

a=1 # a為全局變數

def a_add():

print('a的初值:',a) # 在函數中讀取a的值


a_add() # 調用函數a_add()

a+=1 # 主程序語句,a增加1

print('a現在的值是:',a) # 主程序語句,讀取a的值

運行結果:

a的初值: 1

a現在的值是: 2

這個結果和我們想像的一樣,全局變數a既可以在主程序中讀取,也可以在子程序(函數)中讀取。

程序2:

a=1

def a_add():

a+=1


print('a的初值:',a)

a_add()

print('a現在的值是:',a)

運行程序1時出現如下錯誤提示:

UnboundLocalError: local variable 'a' referenced before assignment

意思是:局部變數'a'在賦值之前被引用。

從語法上來講,該程序沒有錯誤。首先定義了一個全局變數a並賦值為1,又定義了一個函數a_add(),函數內的語句a+=1就是出錯的根源,雖然我們的初衷是想讓全局變數a的值增加1,但從錯誤提示看,這個語句中的a並不是全局變數,而是局部變數。看來,在函數中讀取全局變數的值是沒有問題的(在程序1中已經得到了驗證),但要在函數中改變全局變數的值是不行的(在程序2的錯誤提示a+=1中的a 是局部變數,而非全局變數)。

怎樣解決這個問題?

程序3:

a=1

def a_add(x):

x+=1

return x

print('a的初值:',a)

a=a_add(a)

print('a現在的值是:',a)

運行結果:

a的初值: 1

a現在的值是: 2

結果的確是正確的,但在函數a_add(x)中沒有調用變數a(沒有出現變數a)。

程序4:

a=1

def a_add(a):

a+=1

return a

print('a的初值:',a)

a=a_add(a)

print('a現在的值是:',a)

運行結果:

a的初值: 1

a現在的值是: 2

對比程序4和程序3不難發現,其實程序4隻是簡單的把函數的參數x變成了a,這個a的實質和程序3中的x還是一樣的。這進一步證實,函數中的a是局部變數,與主程序的全局變數a有著本質的區別。

程序5:

a=1

def a_add():

global a

a+=1


print('a的初值:',a)

a_add()

print('a現在的值是:',a)

運行結果:

a的初值: 1

a現在的值是: 2

程序5和程序2相比較,僅僅是在函數中添加了一個定義「global a」,此時的局部變數a就可以當做全局變數使用,由於它和全局變數a同名,自然也就不用區分a究竟是全局變數還是局部變數了,在主程序和該函數內都可以訪問、修改變數a的值了。

雖然使用global可使變數使用起來非常方便,但也容易引起混淆,故在使用過程中還是謹慎為好。

12.3 函數的遞歸與嵌套

遞歸,就是函數調用它自身。遞歸必須設置停止條件,否則函數將無法終止,形成死循環。

以計算階乘為例:

def func(n):

if n==1:

return 1

else:

return n*func(n-1) #func( )調用func( )

print(func(5))

運行結果為:120

嵌套,指在函數中調用另外的函數。這是程序中常見的一種結構,在此不再贅述。

匿名函數

Python中可以在參數前加上關鍵字lambda定義一個匿名函數,這樣的函數一般都屬於「一次性」的。

例如:

程序1:這是一個常規的函數定義和調用。

def f_add(x,y):

return x+y

print(f_add(2,3))

輸出結果:5

程序2:使用lambda定義匿名函數。

f_add=lambda x,y:x+y

print(f_add(2,3))

輸出結果:5

從上面的代碼可以看出,使用lambda僅僅減少了一行代碼。f_add=lambda x,y:x+y中的f_add不是變數名,而是函數名。程序1和程序2的print( )語句中的參數都是一樣的——調用函數f_add( )。所以,匿名函數並沒有太多的優點。

❺ python變數的作用域到底怎麼理解怎麼用呢謝謝!

你可以 在 B頁面 裡面直接 調用 一下 函數
運行一下 ,你可以發現應該和 剛才 執行A 頁面 報的是同樣的錯誤;

這是 因為 在B 頁面裡面 並沒有 s1List 這樣一個數組

在運行A頁面時,因為有了 from b import * ,python解釋器就可以找的getS1和getS2這樣的函數名;可以 在 import 之後 print dir() 來查看 當前作用域下可用的名字 ,可以看到 getS1 和getS2 都在其中

之所以 執行 A頁面錯誤,是A頁面調用 函數 getS1 時,在B頁面中 執行 函數時找不到 s1List這個數組,因為在A 頁面的那個 s1List 是不在 B頁面的作用范圍內的。

❻ 如何在特定的作用域將python系統函數替換成自己的函數

這篇文章主要介紹了Python函數式編程指南(一):函數式編程概述,本文講解了什麼是函數式編程概述、什麼是函數式編程、為什麼使用函數式編程、如何辨認函數式風格等核心知識,需要的朋友可以參考下 1pareTo(o2)) 相信從這個小小的例子你也能感受到強大的生產效率:) 封裝控制結構的內置模板函數 為了避開邊界效應,函數式風格盡量避免使用變數,而僅僅為了控制流程而定義的循環變數和流程中產生的臨時變數無疑是最需要避免的。 假如我們需要對剛才的數集進行過濾得到所有的正數,使用指令式風格的代碼應該像是這樣: 代碼如下: lst2 = list() for i in range(len(lst)): #模擬經典for循環 if lst[i] > 0: lst2.append(lst[i]) 這段代碼把從創建新列表、循環、取出元素、判斷、添加至新列表的整個流程完整的展示了出來,儼然把解釋器當成了需要手把手指導的傻瓜。然而,“過濾”這個動作是很常見的,為什麼解釋器不能掌握過濾的流程,而我們只需要告訴它過濾規則呢? 在Python里,過濾由一個名為filter的內置函數實現。有了這個函數,解釋器就學會了如何“過濾”,而我們只需要把規則告訴它: 代碼如下: lst2 = filter(lambda n: n > 0, lst) 這個函數帶來的好處不僅僅是少寫了幾行代碼這么簡單。 封裝控制結構後,代碼中就只需要描述功能而不是做法,這樣的代碼更清晰,更可讀。因為避開了控制結構的干擾,第二段代碼顯然能讓你更容易了解它的意圖。 另外,因為避開了索引,使得代碼中不太可能觸發下標越界這種異常,除非你手動製造一個。 函數式編程語言通常封裝了數個類似“過濾”這樣的常見動作作為模板函數。唯一的缺點是這些函數需要少量的學習成本,但這絕對不能掩蓋使用它們帶來的好處。 閉包(closure) 閉包是綁定了外部作用域的變數(但不是全局變數)的函數。大部分情況下外部作用域指的是外部函數。 閉包包含了自身函數體和所需外部函數中的“變數名的引用”。引用變數名意味著綁定的是變數名,而不是變數實際指向的對象;如果給變數重新賦值,閉包中能訪問到的將是新的值。 閉包使函數更加靈活和強大。即使程序運行至離開外部函數,如果閉包仍然可見,則被綁定的變數仍然有效;每次運行至外部函數,都會重新創建閉包,綁定的變數是不同的,不需要擔心在舊的閉包中綁定的變數會被新的值覆蓋。 回到剛才過濾數集的例子。假設過濾條件中的 0 這個邊界值不再是固定的,而是由用戶控制。如果沒有閉包,那麼代碼必須修改為: 代碼如下: class greater_than_helper: def __init__(self, minval): self.minval = minval def is_greater_than(self, val): return val > self.minval def my_filter(lst, minval): helper = greater_than_helper(minval) return filter(helper.is_greater_than, lst) 請注意我們現在已經為過濾功能編寫了一個函數my_filter。如你所見,我們需要在別的地方(此例中是類greater_than_helper)持有另一個操作數minval。 如果支持閉包,因為閉包可以直接使用外部作用域的變數,我們就不再需要greater_than_helper了: 代碼如下: def my_filter(lst, minval): return filter(lambda n: n > minval, lst) 可見,閉包在不影響可讀性的同時也省下了不少代碼量。 函數式編程語言都提供了對閉包的不同程度的支持。在Python 2.x中,閉包無法修改綁定變數的值,所有修改綁定變數的行為都被看成新建了一個同名的局部變數並將綁定變數隱藏。Python 3.x中新加入了一個關鍵字 nonlocal 以支持修改綁定變數。但不管支持程度如何,你始終可以訪問(讀取)綁定變數。 內置的不可變數據結構 為了避開邊界效應,不可變的數據結構是函數式編程中不可或缺的部分。不可變的數據結構保證數據的一致性,極大地降低了排查問題的難度。 例如,Python中的元組(tuple)就是不可變的,所有對元組的操作都不能改變元組的內容,所有試圖修改元組內容的操作都會產生一個異常。 函數式編程語言一般會提供數據結構的兩種版本(可變和不可變),並推薦使用不可變的版本。 遞歸 遞歸是另一種取代循環的方法。遞歸其實是函數式編程很常見的形式,經常可以在一些演算法中見到。但之所以放到最後,是因為實際上我們一般很少用到遞歸。如果一個遞歸無法被編譯器或解釋器優化,很容易就會產生棧溢出;另一方面復雜的遞歸往往讓人感覺迷惑,不如循環清晰,所以眾多最佳實踐均指出使用循環而非遞歸。 這一系列短文中都不會關注遞歸的使用。 <第一節完>

❼ python中函數變數作用域和類變數作用域怎麼搞都錯,煩躁中

python中,變數的作用域要弄清楚。只有mole、class、def、lambda才會引入作用域,其他的代碼塊是不會引入作用域的。
1
圖一中,你在函數中聲明了d為全局變數,但這樣是無效的,程序運行結果,已經說明這一點。

global這個關鍵字,是用來「在函數中修改全局變數值」的聲明,而不是「在局部函數中定義一個全局變數」的聲明。這里要注意一下。
你可以再局部函數外面聲明變數d,再加上你原先的函數,就可以修改、訪問這個變數了。

2
在類中函數的變數,作用域只在函數中。圖二中,jian這個變數分別在yu(),yu1()兩個函數中,是處於不同的定義域中的,是不能相互訪問的。
所以,在各自函數中,只有先定義了jian變數,才能再使用。
如果想在yu1()中訪問yu()中的jian變數,就需要將jian變數變成全局變數,即在class中定義一個全局變數jian,這樣yu1(),yu()函數都可以訪問了

❽ PYTHON 的變數作用域與內存分配

原理:python中任何變數都是對象,所以參數只支持引用傳遞方式。即通過名字綁定的機制,把實際參數的值和形式參數的名稱綁定在一起,形式參數和實際參數指向內存中的同一個存儲空間。
回答問題2:
每一次給變數賦值就是把這個名稱的值在一個新內存中存儲
你print
(id
(a))
會發現每一次f(x),a的內存地址都是新的。所以你的問題二中L=[4,3]
與之前的L[]不是同一個名稱,所以append上a就是[4,3,3](簡明點就是L=[4,3]與L=[1,2]是兩不同名的玩意)
討論問題1:
在你的程序中a=1,a=2,a=5是int對象的三個實例,所以佔用的是三段不同的內存,自然在程序執行完收回內存的時候才會被清理;而L是通過列表的append方法進行變化時,print
(f(1))
print
(f(2))
print
(f(5))是對對一個實例進行操作的,所以內存地址不變;
同理print
(f(3,[4,3]))直接給L賦值時,由於
是一個新的列表實例了,內存位置自然變化。
產生以上的問題的根本原因就是python的精髓:萬物皆對象
(賦值的過程是對象的實例化)
看完自己的回答後:感覺真的很繞,不過我是盡力了,希望你能看懂,不明白的話,在追問里註明吧!

閱讀全文

與python替換作用域的參數相關的資料

熱點內容
單片機的控制板 瀏覽:218
襄陽軟體編程 瀏覽:841
sshpass命令 瀏覽:106
logo伺服器怎麼下載 瀏覽:508
如何ftp連接伺服器 瀏覽:674
creo自動編程 瀏覽:161
雲伺服器在電腦怎麼開 瀏覽:432
ipad相冊如何在文件夾中建文件夾 瀏覽:621
和家親這個app有什麼用 瀏覽:575
什麼app裡面有種樹打折 瀏覽:374
編程外掛入門教學 瀏覽:974
pdf黑白轉彩色 瀏覽:725
英國投資加密貨幣嗎 瀏覽:887
看完程序員那麼可愛後的感受 瀏覽:131
廣播在什麼APP能聽 瀏覽:678
阿克曼小車連接什麼app 瀏覽:773
all100編程器 瀏覽:182
加密的內存卡能用嗎 瀏覽:923
linux在線環境 瀏覽:404
java保留兩位小數四捨五入 瀏覽:106