目錄
1.單前導底線:_var
2.單末下劃線var_
3. 雙前導下劃線 __var
4.双前导和双末尾下划线 _var_
5.单下划线 _
首頁 後端開發 Python教學 Python中底線的意思及用法有哪些?

Python中底線的意思及用法有哪些?

Apr 20, 2023 pm 08:04 PM
python

1.單前導底線:_var

當涉及變數和方法名稱時,單一底線前綴有一個約定俗成的含義。它是對程式設計師的提示 - 意味著Python社群一致認為它應該是什麼意思,但程式的行為不受影響。

下劃線前綴的意思是告知其他程式設計師:以單一底線開頭的變數或方法僅供內部使用。該約定在PEP 8中有定義。

這不是Python強制規定的。 Python不像Java在「私有」和「公有」變數之間有很強的區別。這就像有人提出了一個小小的下劃線警告標誌,說:

「嘿,這不是真的要成為類別的公共介面的一部分。不去管它就好。」

2.單末下劃線var_

有時候,一個變數的最適合的名稱已經被一個關鍵字所佔用。因此,像class或def這樣的名稱不能用作Python中的變數名稱。在這種情況下,你可以附加一個底線來解決命名衝突:

>>> def make_object(name, class):
SyntaxError: "invalid syntax"

>>> def make_object(name, class_):
...    pass
登入後複製

總之,單一末尾下劃線(後綴)是一個約定,用來避免與Python關鍵字產生命名衝突。 PEP 8解釋了這個約定。

3. 雙前導下劃線 __var

到目前為止,我們所涉及的所有命名模式的含義,來自於已達成共識的約定。而對於以雙底線開頭的Python類別的屬性(包括變數和方法),情況就有點不同了。

雙底線前綴會導致Python解釋器重寫屬性名稱,以避免子類別中的命名衝突。

這也叫做名稱修飾(name mangling) - 解釋器更改變數的名稱,以便在類別被擴展的時候不容易產生衝突。

我知道這聽起來很抽象。因此,我組合了一個小小的程式碼範例來說明:

class Test:
   def __init__(self):
       self.foo = 11
       self._bar = 23
       self.__baz = 23
登入後複製

讓我們用內建的dir()函數來看看這個物件的屬性:

>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']
登入後複製

以上是這個對象屬性的列表。讓我們來看看這個列表,並尋找我們的原始變數名稱foo,_bar__baz - 我保證你會注意到一些有趣的變化。

self.foo變數在屬性清單中顯示為未修改為foo。 self._bar的行為方式相同 - 它以_bar的形式顯示在類別上。就像我之前說過的,在這種情況下,前導下劃線只是一個約定。給程式設計師一個提示而已。然而,對於self.__baz而言,情況看起來有點不同。當你在該列表中搜尋__baz時,你會看不到有這個名字的變數。

__baz出什麼狀況了?

如果你仔細觀察,你會看到此物件上有一個名為_Test__baz的屬性。這就是Python解釋器所做的名稱修飾。它這樣做是為了防止變數在子類別中被重寫。

讓我們建立另一個擴充Test類別的類,並嘗試重寫建構函式中新增的現有屬性:

class ExtendedTest(Test):
   def __init__(self):
       super().__init__()
       self.foo = 'overridden'
       self._bar = 'overridden'
       self.__baz = 'overridden'
登入後複製

現在,你認為foo,_bar__baz的值會出現在這個ExtendedTest類別的實例上嗎?我們來看看:

>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"
登入後複製

等一下,當我們嘗試查看t2 .__ baz的值時,為什麼我們會得到AttributeError?名稱修飾被再次觸發了!事實證明,這個物件甚至沒有__baz屬性:

>>> dir(t2)
['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']
登入後複製

正如你可以看到__baz變成_ExtendedTest__baz#以防止意外修改:

>>> t2._ExtendedTest__baz
'overridden'
登入後複製

但原來的_Test__baz#還在:

>>> t2._Test__baz
42
登入後複製

雙底線名稱修飾對程式設計師是完全透明的。下面的例子證實了這一點:

class ManglingTest:
   def __init__(self):
       self.__mangled = 'hello'

   def get_mangled(self):
       return self.__mangled

>>> ManglingTest().get_mangled()
'hello'
>>> ManglingTest().__mangled
AttributeError: "'ManglingTest' object has no attribute '__mangled'"
登入後複製

名稱修飾是否也適用於方法名稱?是的,也適用。名稱修飾會影響在一個類別的上下文中,以兩個底線字元("dunders")開頭的所有名稱:

class MangledMethod:
   def __method(self):
       return 42

   def call_it(self):
       return self.__method()

>>> MangledMethod().__method()
AttributeError: "'MangledMethod' object has no attribute '__method'"
>>> MangledMethod().call_it()
42
登入後複製

這是另一個也許令人驚訝的運用名稱修飾的例子:

_MangledGlobal__mangled = 23

class MangledGlobal:
   def test(self):
       return __mangled

>>> MangledGlobal().test()
23
登入後複製

在這個例子中,我宣告了一個名為_MangledGlobal__mangled的全域變數。然後我在名為MangledGlobal的類別的上下文中存取變數。由於名稱修飾,我能夠在類別的test()方法內,以__mangled來引用_MangledGlobal__mangled全域變數。

Python解釋器會自動將名稱__mangled擴展為_MangledGlobal__mangled,因為它以兩個底線字元開頭。這表示名稱修飾不是專門與類別屬性關聯的。它適用於在類別上下文中使用的兩個下劃線字元開頭的任何名稱。

有很多要吸收的內容吧。

老實說,這些例子和解釋不是從我腦中蹦出來的。我做了一些研究和加工才弄出來。我一直使用Python,有很多年了,但像這樣的規則和特殊情況並不總是浮現在腦海裡。

有時候程式設計師最重要的技能是“模式識別”,而且知道在哪裡查閱資訊。如果您在這一點上感到有點不知所措,請不要擔心。慢慢來,試試這篇文章中的一些例子。

让这些概念完全沉浸下来,以便你能够理解名称修饰的总体思路,以及我向您展示的一些其他的行为。如果有一天你和它们不期而遇,你会知道在文档中按什么来查。

4.双前导和双末尾下划线 _var_

也许令人惊讶的是,如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。 由双下划线前缀和后缀包围的变量不会被Python解释器修改:

class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42

>>> PrefixPostfixTest().__bam__
42
登入後複製

但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ — 它使得一个对象可以被调用。

这些dunder方法通常被称为神奇方法 - 但Python社区中的许多人(包括我自己)都不喜欢这种方法。

最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。

5.单下划线 _

按照习惯,有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。

例如,在下面的循环中,我们不需要访问正在运行的索引,我们可以使用“_”来表示它只是一个临时值:

>>> for _ in range(32):
...    print('Hello, World.')
登入後複製

你也可以在拆分(unpacking)表达式中将单个下划线用作“不关心的”变量,以忽略特定的值。 同样,这个含义只是“依照约定”,并不会在Python解释器中触发特殊的行为。 单个下划线仅仅是一个有效的变量名称,会有这个用途而已。

在下面的代码示例中,我将汽车元组拆分为单独的变量,但我只对颜色和里程值感兴趣。 但是,为了使拆分表达式成功运行,我需要将包含在元组中的所有值分配给变量。 在这种情况下,“_”作为占位符变量可以派上用场:

>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12
登入後複製

除了用作临时变量之外,“_”是大多数Python REPL中的一个特殊变量,它表示由解释器评估的最近一个表达式的结果。

这样就很方便了,比如你可以在一个解释器会话中访问先前计算的结果,或者,你是在动态构建多个对象并与它们交互,无需事先给这些对象分配名字:

>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]
登入後複製

以上是Python中底線的意思及用法有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles