㈠ python語言中作用域怎麼理解
命名空間 是從命名到對象的映射。當前命名空間主要是通過 Python 字典實現的,不過通常不關心具體的實現方式(除非出於性能考慮),以後也有可能會改變其實現方式。以下有一些命名空間的例子:內置命名(像 abs() 這樣的函數,以及內置異常名)集,模塊中的全局命名,函數調用中的局部命名。某種意義上講對象的屬性集也是一個命名空間。關於命名空間需要了解的一件很重要的事就是不同命名空間中的命名沒有任何聯系,例如兩個不同的模塊可能都會定義一個名為 maximize 的函數而不會發生混淆-用戶必須以模塊名為前綴來引用它們。
順便提一句,我稱 Python 中任何一個「.」之後的命名為 屬性 --例如,表達式 z.real 中的 real 是對象 z 的一個屬性。嚴格來講,從模塊中引用命名是引用屬性:表達式 modname.funcname 中,modname 是一個模塊對象,funcname 是它的一個屬性。因此,模塊的屬性和模塊中的全局命名有直接的映射關系:它們共享同一命名空間![1]
屬性可以是只讀過或寫的。後一種情況下,可以對屬性賦值。你可以這樣做: modname.the_answer = 42 。可寫的屬性也可以用 del 語句刪除。例如: del modname.the_answer 會從 modname 對象中刪除 the_answer 屬性。
不同的命名空間在不同的時刻創建,有不同的生存期。包含內置命名的命名空間在 Python 解釋器啟動時創建,會一直保留,不被刪除。模塊的全局命名空間在模塊定義被讀入時創建,通常,模塊命名空間也會一直保存到解釋器退出。由解釋器在最高層調用執行的語句,不管它是從腳本文件中讀入還是來自互動式輸入,都是 __main__ 模塊的一部分,所以它們也擁有自己的命名空間(內置命名也同樣被包含在一個模塊中,它被稱作 builtins )。
當調用函數時,就會為它創建一個局部命名空間,並且在函數返回或拋出一個並沒有在函數內部處理的異常時被刪除。(實際上,用遺忘來形容到底發生了什麼更為貼切。)當然,每個遞歸調用都有自己的局部命名空間。
作用域 就是一個 Python 程序可以直接訪問命名空間的正文區域。這里的直接訪問意思是一個對名稱的錯誤引用會嘗試在命名空間內查找。盡管作用域是靜態定義,在使用時他們都是動態的。每次執行時,至少有三個命名空間可以直接訪問的作用域嵌套在一起:
㈡ Python中類的定義規是什麼
類的概念:
類 Class: 用來描述具體相同的屬性和方法的對象的集合。定義了該集合中每個對象所共有的屬性和方法。對象是類的示例。
類變數:類變數在整個實例化的對象中是公用的。類變數定義在類中且在函數體之外。類變數通常不作為實例變數使用。
實例變數:定義在方法中的變數,只作用於當前實例的類。
數據成員:類變數或者實例變數用於處理類及其實例對象的相關數據。
方法:類中定義的函數。在類內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self, 且為第一個參數,self 代表的是類的實例。
構造函數:即__init()__,特殊的方法,在對象創建的時候被自動調用。
析構函數:即__del()__,特殊的方法,在對象被銷毀時被自動調用。
實例化:創建一個類的實例,類的具體對象。就是將創建的類賦值給另一個變數。理解為賦值即可,a = class(),這個過程,就叫做實例化
對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變數和實例變數)和方法。
繼承:即一個派生類(derived class)繼承基類(base class)的欄位和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬」是一個(is-a)」關系(例圖,Dog是一個Animal)。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其 進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
————————————————
原文鏈接:https://blog.csdn.net/f156207495/article/details/81166252
網頁鏈接
㈢ Python 中的import 機制
解釋器 在執行語句時,遵循作用域原則。因為這和作用域有關系, 如果在頂層導入模塊,此時它的作用域是全局的;如果在函數內部導入了模塊,那它的作用域只是局部的 ,不能被其它函數使用。如果其它函數也要用到這個模塊,還需要再次導入比較麻煩。
在用import語句導入模塊時最好按照這樣的順序:
絕對路徑 就是文件的真正存在的路徑,是指從硬碟的根目錄(盤符)開始,進行一級級目錄指向文件。
相對路徑 就是以當前文件為基準進行一級級目錄指向被引用的資源文件。
以下是常用的表示當前目錄和當前目錄的父級目錄的標識符
形如from moleB import ClassB語句,根據Python內部import機制,執行細分步驟:
總結:from moleB import ClassB有兩個過程,先from mole,後import ClassB。
當然將moleA.py語句 from moleB import ClassB改為:import moleB,將在第二次執行moleB.py語句from moleA import ClassA時報錯:ImportError: cannot import name 『classA』
在一個文件下同時有 init .py文件、和其他模塊文件時,該文件夾即看作一個包(package)。包的導入 和模塊導入基本一致,只是導入包時,會執行這個 init .py,而不是模塊中的語句。
而且,如果只是單純地導入包【形如:import xxx】,而包的 init .py中有沒有明確地的其他初始化操作,則:此包下的模塊 是不會被自動導入的。當然該包是會成功導入的,並將包名稱放入當前.py的Local命名空間中。
參考文章:
Python中import機制
Python 3.x可能是史上最詳解的【導入(import)】
在Python中以絕對路徑或者相對路徑導入文件的方法
Python的模塊引用和查找路徑
㈣ python裡面變數作用域是什麼
變數作用域:python可以直接查找名稱到對象的映射(命名空間)的部分。
python有built–in、global、enclosing、local這四種作用域
built–in:內建作用域,包含了內建的變數和關鍵字。
global:全局作用域,定義在所有函數外,當前模塊(.py源文件)的全局變數。
enclosing:閉包函數外的函數(非局部也非全局),比如有一個函數a,a里有另一個函數b,對於b里的變數來說,a中的作用域就是enclosing。
local:局部作用域,腳本最內層,比如函數里。
㈤ 深入探究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對於將來大數據方向、雲計算方向等物聯網時代新興崗位的學習很有幫助。
想要學習Python,需要掌握的內容還是比較多的,對於自學的同學來說會有一些難度,不推薦自學能力差的人。我們將學習的過程劃分為4個階段,每個階段學習對應的內容,具體的學習順序如下:
Python學習順序:
①Python軟體開發基礎
掌握計算機的構成和工作原理
會使用Linux常用工具
熟練使用Docker的基本命令
建立Python開發環境,並使用print輸出
使用Python完成字元串的各種操作
使用Python re模塊進行程序設計
使用Python創建文件、訪問、刪除文件
掌握import 語句、From…import 語句、From…import* 語句、方法的引用、Python中的包
②Python軟體開發進階
能夠使用Python面向對象方法開發軟體
能夠自己建立資料庫,表,並進行基本資料庫操作
掌握非關系資料庫MongoDB的使用,掌握Redis開發
能夠獨立完成TCP/UDP服務端客戶端軟體開發,能夠實現ftp、http伺服器,開發郵件軟體
能開發多進程、多線程軟體
③Python全棧式WEB工程師
能夠獨立完成後端軟體開發,深入理解Python開發後端的精髓
能夠獨立完成前端軟體開發,並和後端結合,熟練掌握使用Python進行全站Web開發的技巧
④Python多領域開發
能夠使用Python熟練編寫爬蟲軟體
能夠熟練使用Python庫進行數據分析
招聘網站Python招聘職位數據爬取分析
掌握使用Python開源人工智慧框架進行人工智慧軟體開發、語音識別、人臉識別
掌握基本設計模式、常用演算法
掌握軟體工程、項目管理、項目文檔、軟體測試調優的基本方法
想要系統學習,你可以考察對比一下開設有IT專業的熱門學校,好的學校擁有根據當下企業需求自主研發課程的能,南京北大青鳥、中博軟體學院、南京課工場等都是不錯的選擇,建議實地考察對比一下。
祝你學有所成,望採納。