中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
下劃線用法
Python下劃線命名模式 - 小結(jié)
以下是一個簡短的小結(jié),即“速查表”,羅列了我在本文中談到的五種Python下劃線模式的含義:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Python 用下劃線作為變量前綴和后綴指定特殊變量/方法。
主要存在四種情形
object # public
__object__ # special, python system use, user should not define like it
__object # private (name mangling during runtime)
_object # obey python coding convention, consider it as private
核心風(fēng)格:避免用下劃線作為變量名的開始。
因為下劃線對解釋器有特殊的意義,而且是內(nèi)建標(biāo)識符所使用的符號,我們建議程序員避免用下劃線作為變量名的開始。一般來講,變量名_object被看作是“私有 的”,在模塊或類外不可以使用,不能用'from moduleimport *'導(dǎo)入。當(dāng)變量是私有的時候,用_object來表示變量是很好的習(xí)慣。因為變量名__object__對Python 來說有特殊含義,對于普通的變量應(yīng)當(dāng)避免這種命名風(fēng)格。
python有關(guān)private的描述,python中不存在protected的概念,要么是public要么就是private,但是python中的private不像C++, Java那樣,它并不是真正意義上的private,通過name mangling(名稱改編(目的就是以防子類意外重寫基類的方法或者屬性),即前面加上“單下劃線”+類名,eg:_Class__object)機制就可以訪問private了。
"單下劃線" 開始的成員變量叫做保護變量,意思是只有類對象和子類對象自己能訪問到這些變量;"雙下劃線" 開始的是私有成員,意思是只有類對象自己能訪問,連子類對象也不能訪問到這個數(shù)據(jù)。(如下列所示)
以單下劃線開頭(_foo)的代表不能直接訪問的類屬性,需通過類提供的接口進行訪問,不能用“from xxx import *”而導(dǎo)入;以雙下劃線開頭的(__foo)代表類的私有成員;以雙下劃線開頭和結(jié)尾的(__foo__)代表python里特殊方法專用的標(biāo)識,如 __init__()代表類的構(gòu)造函數(shù)。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
class Foo():
def __init__():
...
def public_method():
print 'This is public method'
def __fullprivate_method():
print 'This is double underscore leading method'
def _halfprivate_method():
print 'This is one underscore leading method'
實例化Foo的一個對象,
f = Foo()
f.public_method() # OK
f.__fullprivate_method() # Error occur
f._halfprivate_method() # OK
f._Foo__fullprivate()_method() # OK
從上面的例子可以看出,f._halfprivate_method()可以直接訪問,確實是。不過根據(jù)python的約定,應(yīng)該將其視作private,而不要在外部使用它們,(如果你非要使用也沒轍),良好的編程習(xí)慣是不要在外部使用它。同時,根據(jù)Python docs的說明,_object和__object的作用域限制在本模塊內(nèi)。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
理解Python命名機制(單雙下劃線開頭)  (轉(zhuǎn)載:http://blog.csdn.net/lanphaday)
引子
我熱情地邀請大家猜測下面這段程序的輸出:
class A(object):
def __init__(self):
self.__private()
self.public()
def __private(self):
print 'A.__private()'
def public(self):
print 'A.public()'
class B(A):
def __private(self):
print 'B.__private()'
def public(self):
print 'B.public()'
b = B()
初探
正確的答案是:
A.__private()
B.public()
如果您已經(jīng)猜對了,那么可以不看我這篇博文了。如果你沒有猜對或者心里有所疑問,那我的這篇博文正是為您所準備的。
一切由為什么會輸出“A.__private()”開始。但要講清楚為什么,我們就有必要了解一下Python的命名機制。
據(jù) Python manual,變量名(標(biāo)識符)是Python的一種原子元素。當(dāng)變量名被綁定到一個對象的時候,變量名就指代這個對象,就像人類社會一樣,不是嗎?當(dāng)變 量名出現(xiàn)在代碼塊中,那它就是本地變量;當(dāng)變量名出現(xiàn)在模塊中,它就是全局變量。模塊相信大家都有很好的理解,但代碼塊可能讓人費解些。在這里解釋一下:
代碼塊就是可作為可執(zhí)行單元的一段Python程序文本;模塊、函數(shù)體和類定義都是代碼塊。不僅如此,每一個交互腳本命令也是一個代碼塊;一個腳本文件也是一個代碼塊;一個命令行腳本也是一個代碼塊。
接下來談?wù)勛兞康目梢娦?,我們引入一個范圍的概念。范圍就是變量名在代碼塊的可見性。 如果一個代碼塊里定義本地變量,那范圍就包括這個代碼塊。如果變量定義在一個功能代碼塊里,那范圍就擴展到這個功能塊里的任一代碼塊,除非其中定義了同名 的另一變量。但定義在類中的變量的范圍被限定在類代碼塊,而不會擴展到方法代碼塊中。
迷蹤
據(jù)上節(jié)的理論,我們可以把代碼分為三個代碼塊:類A的定義、類B的定義和變量b的定義。根據(jù)類定義,我們知道代碼給類A定義了三個成員變量(Python的函數(shù)也是對象,所以成員方法稱為成員變量也行得通。);類B定義了兩個成員變量。這可以通過以下代碼驗證:
>>> print '\n'.join(dir(A))
_A__private
__init__
public
>>> print '\n'.join(dir(B))
_A__private
_B__private
__init__
public
咦,為什么類A有個名為_A__private的 Attribute 呢?而且__private消失了!這就要談?wù)凱ython的私有變量軋壓了。
探究
懂Python的朋友都知道Python把以兩個或以上下劃線字符開頭且沒有以兩個或以上下劃線結(jié)尾的變量當(dāng)作私有變量。私有變量會在代碼生成之前被轉(zhuǎn)換為長格式(變?yōu)楣校?。轉(zhuǎn)換機制是這樣的:在變量前端插入類名,再在前端加入一個下劃線字符。這就是所謂的私有變量軋壓(Private name mangling)。如類 A里的__private標(biāo)識符將被轉(zhuǎn)換為_A__private,這就是上一節(jié)出現(xiàn)_A__private和__private消失的原因了。
再講兩點題外話:
一是因為軋壓會使標(biāo)識符變長,當(dāng)超過255的時候,Python會切斷,要注意因此引起的命名沖突。
二是當(dāng)類名全部以下劃線命名的時候,Python就不再執(zhí)行軋壓。如:
>>> class ____(object):
def __init__(self):
self.__method()
def __method(self):
print '____.__method()'
>>> print '\n'.join(dir(____))
__class__
__delattr__
__dict__
__doc__
__getattribute__
__hash__
__init__
__method              # 沒被軋壓
__module__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__str__
__weakref__
>>> obj = ____()
____.__method()
>>> obj.__method()      # 可以外部調(diào)用
____.__method()
現(xiàn)在我們回過頭來看看為什么會輸出“A.__private()”吧!
真相
相信現(xiàn)在聰明的讀者已經(jīng)猜到答案了吧?如果你還沒有想到,我給你個提示:真相跟C語言里的宏預(yù)處理差不多。
因為類A定義了一個私有成員函數(shù)(變量),所以在代碼生成之前先執(zhí)行私有變量軋壓(注意到上一節(jié)標(biāo)紅的那行字沒有?)。軋壓之后,類A的代碼就變成這樣了:
class A(object):
def __init__(self):
self._A__private()          # 這行變了
self.public()
def _A__private(self):           # 這行也變了
print 'A.__private()'
def public(self):
print 'A.public()'
是不是有點像C語言里的宏展開???
因為在類B定義的時候沒有覆蓋__init__方法,所以調(diào)用的仍然是A.__init__,即執(zhí)行了self._A__private(),自然輸出“A.__private()”了。
下面的兩段代碼可以增加說服力,增進理解:
>>> class C(A):
def __init__(self):          # 重寫 __init__ ,不再調(diào)用 self._A__private
self.__private()       # 這里綁定的是 _C_private
self.public()
def __private(self):
print 'C.__private()'
def public(self):
print 'C.public()'
>>> c = C()
C.__private()
C.public()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
>>> class A(object):
def __init__(self):
self._A__private()   # 調(diào)用一個沒有定義的函數(shù), Python 會把它給我的
self.public()
def __private(self):
print 'A.__private()'
def public(self):
print 'A.public()'
>>>a = A()
A.__private()
A.public()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
特殊方法一覽表
Model 一章列出了 83 個特殊方法的名字, 其中 47 個用于實現(xiàn)算術(shù)運算、 位運算和比較操作
1. 類的基礎(chǔ)方法
序號目的所編寫代碼Python 實際調(diào)用
①初始化一個實例x = MyClass()x.__init__()
②字符串的 “官方” 表現(xiàn)形式repr(x)x.__repr__()
③字符串的“非正式”值str(x)x.__str__()
④字節(jié)數(shù)組的“非正式”值bytes(x)x.__bytes__()
⑤格式化字符串的值format(x, format_spec)x.__format__(format_spec)
按照約定, repr() 方法所返回的字符串為合法的 Python 表達式
在調(diào)用 print(x) 的同時也調(diào)用了 str() 方法
2.迭代枚舉
序號目的所編寫代碼Python 實際調(diào)用
①遍歷某個序列iter(seq)seq.__iter__()
②從迭代器中獲取下一個值next(seq)seq.__next__()
③按逆序創(chuàng)建一個迭代器reversed(seq)seq.__reversed__()
無論何時創(chuàng)建迭代器都將調(diào)用 iter() 方法。這是用初始值對迭代器進行初始化的絕佳之處。
無論何時從迭代器中獲取下一個值都將調(diào)用 next() 方法。
__reversed__() 方法并不常用。它以一個現(xiàn)有序列為參數(shù),并將該序列中所有元素從尾到頭以逆序排列生成一個新的迭代器
3. 屬性管理
序號目的所編寫代碼Python 實際調(diào)用
①獲取一個計算屬性(無條件的)x.my_propertyx.__getattribute__('my_property')
②獲取一個計算屬性(后備)x.my_propertyx.__getattr__('my_property')
③設(shè)置某屬性x.my_property = valuex.__setattr__('my_property',value)
④刪除某屬性del x.my_propertyx.__delattr__('my_property')
⑤列出所有屬性和方法dir(x)x.__dir__()
如果某個類定義了 __getattribute__() 方法,在 每次引用屬性或方法名稱時 Python 都調(diào)用它(特殊方法名稱除外,因為那樣將會導(dǎo)致討厭的無限循環(huán))。
如果某個類定義了 __getattr__() 方法,Python 將只在正常的位置查詢屬性時才會調(diào)用它。如果實例 x 定義了屬性color, x.color 將 不會 調(diào)用 x.__getattr__('color');而只會返回x.color 已定義好的值
無論何時給屬性賦值,都會調(diào)用 __setattr__()方法
無論何時刪除一個屬性,都將調(diào)用__delattr__()方法
如果定義了 __getattr__() 或 __getattribute__() 方法, __dir__() 方法將非常有用。通常,調(diào)用 dir(x)將只顯示正常的屬性和方法。如果__getattr()__方法動態(tài)處理 color 屬性, dir(x) 將不會將 color 列為可用屬性??赏ㄟ^覆蓋 __dir__() 方法允許將 color 列為可用屬性,對于想使用你的類但卻不想深入其內(nèi)部的人來說,該方法非常有益
4. 可序列化的類
Python 支持 任意對象的序列化和反序列化。(多數(shù) Python 參考資料稱該過程為 pickling 和 unpickling)。該技術(shù)對與將狀態(tài)保存為文件并在稍后恢復(fù)它非常有意義。所有的 內(nèi)置數(shù)據(jù)類型 均已支持 pickling 。如果創(chuàng)建了自定義類,且希望它能夠 pickle,閱讀 pickle 協(xié)議 了解下列特殊方法何時以及如何被調(diào)用
序號目的所編寫代碼Python 實際調(diào)用
①自定義對象的復(fù)制copy.copy(x)x.__copy__()
②自定義對象的深度復(fù)制copy.deepcopy(x)x.__deepcopy__()
③在 pickling 之前獲取對象的狀態(tài)pickle.dump(x, file)x.__getstate__()
④序列化某對象pickle.dump(x, file)x.__reduce__()
⑤序列化某對象(新 pickling 協(xié)議)pickle.dump(x, file, protocol_version)x.__reduce_ex__(protocol_version)
⑥控制 unpickling 過程中對象的創(chuàng)建方式x = pickle.load(file)x.__getnewargs__()
⑦在 unpickling 之后還原對象的狀態(tài)x = pickle.load(file)x.__setstate__()
要重建序列化對象,Python 需要創(chuàng)建一個和被序列化的對象看起來一樣的新對象,然后設(shè)置新對象的所有屬性。__getnewargs__() 方法控制新對象的創(chuàng)建過程,而 __setstate__() 方法控制屬性值的還原方式
總結(jié)
單下劃線 (_)
1、在 CPython 等解釋器中代表交互式解釋器會話中上一條執(zhí)行的語句的結(jié)果
2、作為臨時性的名稱使用,分配了一個特定的名稱但是在后面不會用到該名稱
3、用于實現(xiàn)國際化和本地化字符串之間翻譯查找的函數(shù)名稱(遵循相應(yīng)的C約定)
4、名稱前的單下劃線,用于指定該名稱屬性為 私有,這并不是語法規(guī)定而是慣例,在使用這些代碼時將大家會知道以 _ 開頭的名稱只供內(nèi)部使用,在 from <Package> import * 時,以 _ 開頭的名稱都不會被導(dǎo)入,除非模塊或包中的 __all__ 列表顯式地包含了它們
雙下劃線 (__)
1、名稱(具體為一個方法名)前雙下劃線(__)的用法并不是一種慣例,對解釋器來說它有特定的意義。Python 中的這種用法是為了避免與子類定義的名稱沖突。Python文檔指出,__spam 這種形式(至少兩個前導(dǎo)下劃線,最多一個后續(xù)下劃線)的任何標(biāo)識符將會被 _classname__spam 這種形式原文取代,在這里 classname 是去掉前導(dǎo)下劃線的當(dāng)前類名
2、名稱前后的雙下劃線表示 Python 中特殊的方法名。這只是一種慣例,對 Python 來說,這將確保不會與用戶自定義的名稱沖突。通常,程序員會重寫這些方法,并在里面實現(xiàn)所需要的功能,以便Python 調(diào)用
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
理解Python的雙下劃線命名(轉(zhuǎn)過來慢慢理解)
史上最全的Python面向?qū)ο笾R點疏理
兩分鐘掌握Python中下劃線 ‘_’ 用法
我來考考你!Python中下劃線的5種含義你都知道嗎?
Python類中的 私有變量和私有方法
python _、__和__xx__的區(qū)別
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服