av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

python 下劃線的多種應(yīng)用場(chǎng)景總結(jié)

瀏覽:4日期:2022-06-19 18:56:06
目錄一、_用于臨時(shí)變量1.1 REPL1.2 for循環(huán)中的_1.3 元組拆包中的_1.4 國(guó)際化函數(shù)1.5 大數(shù)字表示形式二、var_用于解決命名沖突問(wèn)題三、_var用于保護(hù)變量3.1 突破保護(hù)屬性四、__var用于私有變量4.1 突破私有屬性五、__var__用于魔術(shù)方法5.1 Python魔術(shù)方法分類六、總結(jié)

目前常見(jiàn)的用法有五種:

_用于臨時(shí)變量 var_用于解決命名沖突問(wèn)題 _var用于保護(hù)變量 __var用于私有變量 __var__用于魔術(shù)方法

下面我們具體看看這些下劃線應(yīng)用場(chǎng)景。

一、_用于臨時(shí)變量

單下劃線一般用于表示臨時(shí)變量,在REPL、for循環(huán)和元組拆包等場(chǎng)景中比較常見(jiàn)。

1.1 REPL

單下劃線在REPL中關(guān)聯(lián)的是上一次計(jì)算的非None結(jié)果。

>>> 1+12>>> _2>>> a=2+2>>> _2

1+1,結(jié)果為2,賦值給_;而賦值表達(dá)式a=2+2a為4,但整個(gè)表達(dá)式結(jié)果為None,故不會(huì)關(guān)聯(lián)到_。這有點(diǎn)類似日常大家使用的計(jì)算器中的ANS按鍵,直接保存了上次的計(jì)算結(jié)果。

1.2 for循環(huán)中的_

for循環(huán)中_作為臨時(shí)變量用。下劃線來(lái)指代沒(méi)什么意義的變量。例如在如下函數(shù)中,當(dāng)我們只關(guān)心函數(shù)執(zhí)行次數(shù),而不關(guān)心具體次序的情況下,可以使用_作為參數(shù)。

nums = 13for _ in range(nums): fun_oper()1.3 元組拆包中的_

第三個(gè)用法是元組拆包,賦值的時(shí)候可以用_來(lái)表示略過(guò)的內(nèi)容。如下代碼忽略北京市人口數(shù),只取得名字和區(qū)號(hào)。

>>> city,_,code = (’Beijing’,21536000,’010’)>>> print(city,code)Beijing 010

如果需要略過(guò)的內(nèi)容多于一個(gè)的話,可以使用*開(kāi)頭的參數(shù),表示忽略多個(gè)內(nèi)容。如下代碼忽略面積和人口數(shù),只取得名字和區(qū)號(hào)

city,*_,code = (’Beijing’,21536000,16410.54,’010’)1.4 國(guó)際化函數(shù)

在一些國(guó)際化編程中,_常用來(lái)表示翻譯函數(shù)名。例如gettext包使用時(shí):

import gettextzh = gettext.tranlation(’dict’,’locale’,languages=[’zh_CN’])zh.install()_(’hello world’)

依據(jù)設(shè)定的字典文件,其返回相應(yīng)的漢字“你好世界”。

1.5 大數(shù)字表示形式

_也可用于數(shù)字的分割,這在數(shù)字比較長(zhǎng)的時(shí)候常用。

>>> a = 9_999_999_999>>> a9999999999

a的值自動(dòng)忽略了下劃線。這樣用_分割數(shù)字,有利于便捷讀取比較大的數(shù)。

二、var_用于解決命名沖突問(wèn)題

變量后面加一個(gè)下劃線。主要用于解決命名沖突問(wèn)題,元編程中遇時(shí)Python保留的關(guān)鍵字時(shí),需要臨時(shí)創(chuàng)建一個(gè)變量的副本時(shí),都可以使用這種機(jī)制。

def type_obj_class(name,class_): passdef tag(name,*content,class_): pass

以上代碼中出現(xiàn)的class是Python的保留關(guān)鍵字,直接使用會(huì)報(bào)錯(cuò),使用下劃線后綴的方式解決了這個(gè)問(wèn)題。

三、_var用于保護(hù)變量

前面一個(gè)下劃線,后面加上變量,這是僅供內(nèi)部使用的“保護(hù)變量”。比如函數(shù)、方法或者屬性。

這種保護(hù)不是強(qiáng)制規(guī)定,而是一種程序員的約定,解釋器不做訪問(wèn)控制。一般來(lái)講這些屬性都作為實(shí)現(xiàn)細(xì)節(jié)而不需要調(diào)用者關(guān)心,隨時(shí)都可能改變,我們編程時(shí)雖然能訪問(wèn),但是不建議訪問(wèn)。

這種屬性,只有在導(dǎo)入時(shí),才能發(fā)揮保護(hù)作用。而且必須是from XXX import *這種導(dǎo)入形式才能發(fā)揮保護(hù)作用。

使用from XXX import *是一種通配導(dǎo)入(wildcard import),這是Python社區(qū)不推薦的方式,因?yàn)槟愀靖悴磺迥愕降讓?dǎo)入了什么屬性、方法,很可能搞亂你自己的命名空間。PEP8推薦的導(dǎo)入方式是from XXX import aVar , b_func , c_func這種形式。

比如在下例汽車庫(kù)函數(shù)tools.py里定義的“保護(hù)屬性”:發(fā)動(dòng)機(jī)型號(hào)和輪胎型號(hào),這屬于實(shí)現(xiàn)細(xì)節(jié),沒(méi)必要暴露給用戶。當(dāng)我們使用from tools import * 語(yǔ)句調(diào)用時(shí),其實(shí)際并沒(méi)有導(dǎo)入所有_開(kāi)頭的屬性,只導(dǎo)入了普通drive方法。

_moto_type = ’L15b2’_wheel_type = ’michelin’def drive(): _start_engine() _drive_wheel()def _start_engine(): print(’start engine %s’%_moto_type) def _drive_wheel(): print(’drive wheel %s’%_wheel_type)

查看命令空間print(vars())可見(jiàn),只有drive函數(shù)被導(dǎo)入進(jìn)來(lái),其他下劃線開(kāi)頭的“私有屬性”都沒(méi)有導(dǎo)入進(jìn)來(lái)。

{’__name__’: ’__main__’, ’__doc__’: None, ’__package__’: None, ’__loader__’: <_frozen_importlib_external.SourceFileLoader object at 0x005CF868>, ’__spec__’: None, ’__annotations__’:{}, ’__builtins__’: <module ’builtins’ (built-in)>, ’__file__’: ’.xiahuaxian.py’, ’__cached__’: None, ’walk’: <function walk at 0x01DA8C40>, ’root’: ’.__pycache__’, ’_’: [21536000, 16410.54], ’dirs’: [’tools.cpython-38.pyc’], ’city’: ’Beijing’, ’code’: ’010’, ’drive’: <function drive at 0x01DBC4A8>}3.1 突破保護(hù)屬性

之所以說(shuō)是“保護(hù)”并不是“私有”,是因?yàn)镻ython沒(méi)有提供解釋器機(jī)制來(lái)控制訪問(wèn)權(quán)限。我們依然可以訪問(wèn)這些屬性:

import toolstools._moto_type = ’EA211’tools.drive()

以上代碼,以越過(guò)“保護(hù)屬性”。此外,還有兩種方法能突破這個(gè)限制,一種是將“私有屬性”添加到tool.py文件的__all__列表里,使from tools import *也導(dǎo)入這些本該隱藏的屬性。

__all__ = [’drive’,’_moto_type’,’_wheel_type’]

另一種是導(dǎo)入時(shí)指定“受保護(hù)屬性”名。

from tools import drive,_start_engine_start_engine()

甚至是,使用import tools也可以輕易突破保護(hù)限制。所以可見(jiàn),“保護(hù)屬性”是一種簡(jiǎn)單的隱藏機(jī)制,只有在from tools import *時(shí),由解釋器提供簡(jiǎn)單的保護(hù),但是可以輕易突破。這種保護(hù)更多地依賴程序員的共識(shí):不訪問(wèn)、修改“保護(hù)屬性”。除此之外,有沒(méi)有更安全的保護(hù)機(jī)制呢?有,就是下一部分討論的私有變量。

四、__var用于私有變量

私有屬性解決的之前的保護(hù)屬性保護(hù)力度不夠的問(wèn)題。變量前面加上兩個(gè)下劃線,類里面作為屬性名和方法都可以。兩個(gè)下劃線屬性由Python的改寫機(jī)制來(lái)實(shí)現(xiàn)對(duì)這個(gè)屬性的保護(hù)。

看下面汽車?yán)又校放茷槠胀▽傩裕l(fā)動(dòng)機(jī)為“保護(hù)屬性”,車輪品牌為“私有屬性”。

class Car: def __init__(self):self.brand = ’Honda’self._moto_type = ’L15B2’self.__wheel_type = ’michelin’ def drive(self):print(’Start the engine %s,drive the wheel %s,I get a running %s car’%(self._moto_type,self.__wheel_type,self.brand))

我們用var(car1)查看下具體屬性值,

[’_Car__wheel_type’, ’__class__’, ’__delattr__’, ’__dict__’, ’__dir__’, ’__doc__’, ’__eq__’, ’__format__’, ’__ge__’, ’__getattribute__’, ’__gt__’, ’__hash__’, ’__init__’, ’__init_subclass__’, ’__le__’, ’__lt__’, ’__module__’, ’__ne__’, ’__new__’, ’__reduce__’, ’__reduce_ex__’, ’__repr__’, ’__setattr__’, ’__sizeof__’, ’__str__’, ’__subclasshook__’, ’__weakref__’, ’_moto_type’, ’brand’, ’drive’]

可見(jiàn),實(shí)例化car1中,普通屬性self.brand和保護(hù)屬性self._moto_type都得以保存,兩個(gè)下劃線的私有屬性__wheel_type沒(méi)有了。取而代之的是_Car_wheel_type這個(gè)屬性。這就是改寫機(jī)制(Name mangling)。兩個(gè)下劃線的屬性,被改寫成帶有類名前綴的變量,這樣子類很難明明一個(gè)和如此復(fù)雜名字重名的屬性。保證了屬性不被重載,保證了其的私有性。

4.1 突破私有屬性

這里“私有變量”的實(shí)現(xiàn),是從解釋器層面給與的改寫,保護(hù)了私有變量。但是這個(gè)機(jī)制并非絕對(duì)安全,因?yàn)槲覀円廊豢梢酝ㄟ^(guò)obj._ClasssName__private來(lái)訪問(wèn)__private私有屬性。

car1.brand = ’Toyota’car1._moto_type = ’6AR-FSE’car1._Car__wheel_type = ’BRIDGESTONE’car1.drive()

結(jié)果

Start the engine 6AR-FSE,drive the wheel BRIDGESTONE,I get a running Toyota car

可見(jiàn),對(duì)改寫機(jī)制改寫的私有變量,雖然保護(hù)性加強(qiáng)了,但依然可以訪問(wèn)并修改。只是這種修改,只是一種雜耍般的操作,并不可取。

五、__var__用于魔術(shù)方法

變量前面兩個(gè)下劃線,后面兩個(gè)下劃線。這是Python當(dāng)中的魔術(shù)方法,一般是給系統(tǒng)程序調(diào)用的。例如上例中的__init__就是類的初始化魔術(shù)方法,還有支持len函數(shù)的__len__方法,支持上下文管理器協(xié)議的__enter__和__exit__方法,支持迭代器協(xié)議的__iter__方法,支持格式化顯示的__repr__和__str__方法等等。這里我們?yōu)樯侠腃ar類添加魔術(shù)方法__repr__來(lái)支持格式化顯示。

def __repr__(self):return ’***Car %s:with %s Engine,%sWheel***’%(self.brand,self._moto_type,self.__wheel_type)

未添加__repr__魔術(shù)方法之前,print(car1)結(jié)果為<__main__.Car object at 0x0047F7F0>,這個(gè)結(jié)果讓人看的一頭霧水,增加repr魔術(shù)方法之后,顯示結(jié)果為***Car Toyota:with 6AR-FSE Engine,BRIDGESTONE Wheel***清晰明了,利于調(diào)試。這就是魔術(shù)方法的功效:支持系統(tǒng)調(diào)用,改進(jìn)用戶類表現(xiàn),增加協(xié)議支持,使用戶類表現(xiàn)得更像系統(tǒng)類。

5.1 Python魔術(shù)方法分類

以下所有魔術(shù)方法均需要在前后加上__,這里省略了這些雙下劃線。

一元運(yùn)算符 neg pos abs invert 轉(zhuǎn)換 complex int float round inex 算術(shù)運(yùn)算 add sub mul truediv floordiv mod divmod pow lshift rshift and xor or

算術(shù)運(yùn)算除and之外,前面再加上r,表示反運(yùn)算。除dimod外,前面加上i,表示就地運(yùn)算。

比較 lt le eq ne gt ge 類屬性 getattr getattribute setattr delattr dir get set delete 格式化 bytes hash bool format 類相關(guān) init del new 列表 getitem 迭代器 iter next 上下文管理器 enter exit 六、總結(jié)

總之,下劃線在 Python 當(dāng)中應(yīng)用還是很廣泛的,甚至可以說(shuō) Python 對(duì)下劃線有所偏愛(ài)

可以看到 _常用于臨時(shí)變量,在REPL,for循環(huán),元組拆包和國(guó)際化中得到了廣泛應(yīng)用

var_用于解決命名沖突問(wèn)題,使用時(shí)比較簡(jiǎn)單易懂的。_var對(duì)變量的保護(hù),只是一種脆弱的保護(hù),更多依靠程序員的約定。__var用于私有變量,借助改寫機(jī)制支持,已經(jīng)支持了私有變量,但是仍然存在漏洞

對(duì)__var__用于魔術(shù)方法,進(jìn)行了一個(gè)簡(jiǎn)單的介紹,魔術(shù)方法較多,但是理解并不復(fù)雜。希望以后可以進(jìn)一步介紹這些魔術(shù)方法

以上就是python 下劃線的多種應(yīng)用場(chǎng)景總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于python 下劃線應(yīng)用場(chǎng)景的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 爱操av | 欧美一区二区三区在线看 | 免费在线成人 | 在线观看国产wwwa级羞羞视频 | 欧美一区2区三区4区公司 | 国产精品免费一区二区三区 | 成人午夜激情 | 超碰在线播 | 请别相信他免费喜剧电影在线观看 | 亚洲国产精品第一区二区 | 999久久久| 日韩精品欧美精品 | 黄色一级大片视频 | 欧美一级片a | 99久久久国产精品 | 欧美日产国产成人免费图片 | 性网站免费 | 超碰520| 波多野结衣在线观看一区二区三区 | 久久国际精品 | 蜜桃精品视频在线 | 一区二区三区观看视频 | 狠狠色狠狠色综合日日92 | 日日骚网 | 日韩av在线一区二区 | 国产精品乱码一区二三区小蝌蚪 | 亚州视频在线 | 日韩欧美一区二区三区免费观看 | 一区二区三区免费 | 国产精品久久久久久久久久久久冷 | 亚洲一级毛片 | 成人精品一区二区三区中文字幕 | 午夜资源| 干狠狠| 久久精品亚洲精品国产欧美 | 国产伦精品一区二区三区高清 | 日韩电影一区 | 精品国产一区二区三区久久久蜜月 | 国产精品视频区 | 精品一区二区三区入口 | 国产中文字幕在线观看 |