Python中的下劃線

2021-09-01 21:01:48 字數 3633 閱讀 6327

雙下劃線

感謝018.11.25

我發現公司裡即便是工作經驗一年的程式設計師依然對python的私有屬性有些迷糊——也就是下劃線的問題——拿捏不准要怎麼用。我想在此總結一下。

前置單下劃線是一種約定,即:認為這個變數或方法是類私有,外界不要呼叫。在這裡,物件認為是「外界」。

示例如下:

class

persion

(object):

def__init__

(self, name, age, hobbies)

:# 不建議被外界使用

self._name = name

self._age = age

self._hobbies = hobbies

# 允許被外界呼叫

@property

defdetail

(self)

:return self._get_sentence(

)# 建議不要被外界呼叫,而是在類中使用

def_get_sentence

(self)

:return f" is and loves ."

if __name__ ==

"__main__"

: lily = persion(

"lily",18

,"listenning"

)print

(lily.detail)

# 輸出:

# lily is 18 and loves listenning.

但外界能不能呼叫帶前置單下劃線的成員變數和成員方法呢?事實上是可以的:

print

(lily._name)

# 輸出:lily

print

(lily._get_sentence())

# 輸出: lily is 18 and loves listening.

我實在記不清是《python程式設計之美》還是《資料結構(python描述)》,裡面對此解釋說:之所以python對類私有只是一種約定,是認為使用python開發的程式設計師應該是成熟的。

而另一方面,在乙個模組中,前置單下劃線的變數或是函式,不能通過from module import *方式匯入。如:

# demo1.py

# 這是乙個變數

_one =

"one"

# 這是乙個函式

def_two()

:print

("two"

)

# demo2.py

from demo1 import

*print

(_one)

# 錯誤使用

_two(

)# 錯誤使用

對此直譯器會丟擲異常:nameerror: name '***' is not defined

但並非demo1中的前置單下劃線變數/方法在demo2中就不可以使用,完全可以import module,然後通過module.***方式,demo2**做如下調整:

# demo2.py

import demo1

print

(demo1._one)

# 正確使用

demo1._two(

)# 正確使用

後置單下劃線是一種程式設計風格建議,即:當你的變數/方法名與python中的關鍵字衝突時,可以加上後置單下劃線做區分。如:

list_ =

["lily"

,"bob"

,"green"

]dict_ =

事實上,前置雙下劃線變數/方法,更像是類私有。將第乙個示例**改寫如下(單下劃線都改寫為雙下劃線):

class

persion

(object):

def__init__

(self, name, age, hobbies)

:# 不能被外界訪問

self.__name = name

self.__age = age

self.__hobbies = hobbies

# 允許被外界呼叫

@property

defdetail

(self)

:return self.__get_sentence(

)# 不能被外界呼叫

def__get_sentence

(self)

:return f" is and loves ."

if __name__ ==

"__main__"

: lily = persion(

"lily",18

,"listening"

)print

(lily.detail)

# 輸出:

# lily is 18 and loves listening.

可如果你想外界訪問:

print

(lily.__name)

# 錯誤示例

print

(lily.__get_sentence())

# 錯誤示例

直譯器會拋異常:attributeerror: 'persion' object has no attribute '__name'

其實同前置單下劃線一樣,雙下劃線其實也可以被外界訪問,只不過直譯器對他們**「以類之姓,冠它之名」**。

print

(lily._persion__name)

# 輸出:lily

lily._persion__get_sentence(

)# 輸出:lily is 18 and loves listening.

也就是說,當類名為x,雙下劃線變數為__y時,外界對其訪問應該形如:_x__y

完全與前置單下劃線一樣的是,模組中的前置雙下劃線變數/函式,不能通過from module import *匯入,但可以import module後使用:

module.__one

module.__two(

)

前置雙下劃線存在的意義:為了避免該成員的名稱與子類中的名稱衝突

開個玩笑。

後置雙下劃線既沒有實際意義,也不是程式設計風格的建議。

稍微對python熟悉的人就會知道,存在前置雙下劃線同時還有後置雙下劃線的變數以及方法。如常見的__name__以及__init__()。這些屬於python的魔法物件,是為了區別其他使用者自定義的命名。官方表示:永遠不要將這樣的命名方式應用於自己的變數或函式

Python中單下劃線和雙下劃線

python中存在一些特殊的方法,有些方法以雙下劃線 開頭和結尾,它們是python的魔法函式,比如 init 和 str 等等。不用要這種方式命名自己的變數或者函式。class a def init self,text self.text text def str self return self...

Python中單下劃線和雙下劃線

雙下劃線開頭和結尾 python中存在一些特殊的方法,有些方法以雙下劃線 開頭和結尾,它們是python的魔法函式,比如 init 和 str 等等。不用要這種方式命名自己的變數或者函式。classa def init self,text self.text text def str self re...

python中單下劃線 和雙下劃線(

函式使用單下劃線 開頭 使用單下劃線 開頭的函式 func不能被模組外部以 from module www.cppcns.comimport 形式匯入。但程式設計客棧可以用 from module import func形式單獨匯入。類屬性和類方法使用單下劃線 開頭 開頭為保護型別的屬性和方法,僅允...