天天看點

python中那些雙下劃線開頭得函數和變量

_xxx 不能用’from module import *’導入

__xxx__ 系統定義名字

__xxx 類中的私有變量名

核心風格避免用下劃線作為變量名的開始。

因為下劃線對解釋器有特殊的意義而且是内建辨別符所使用的符号我們建議程式員避免用下劃線作為變量名的開始。一般來講變量名_xxx被看作是“私有 的”在子產品或類外不可以使用。當變量是私有的時候用_xxx 來表示變量是很好的習慣。因為變量名__xxx__對Python 來說有特殊含義對于普通的變量應當避免這種命名風格。

“單下劃線” 開始的成員變量叫做保護變量意思是隻有類對象和子類對象自己能通路到這些變量

“雙下劃線” 開始的是私有成員意思是隻有類對象自己能通路連子類對象也不能通路到這個資料。

以單下劃線開頭_foo的代表不能直接通路的類屬性需通過類提供的接口進行通路不能用“from xxx import *”而導入以雙下劃線開頭的__foo代表類的私有成員以雙下劃線開頭和結尾的__foo__代表python裡特殊方法專用的辨別如 __init__代表類的構造函數。

現在我們來總結下所有的系統定義屬性和方法 先來看下保留屬性

序号

目的

所編寫代碼

Python 實際調用

初始化一個執行個體

<code>x = MyClass()</code>

<a href="http://docs.python.org/3.1/reference/datamodel.html#object.__init__" target="_blank">x.__init__()</a>

字元串的“官方”表現形式

<code>repr(x)</code>

<a href="http://docs.python.org/3.1/reference/datamodel.html#object.__repr__" target="_blank">x.__repr__()</a>

字元串的“非正式”值

<a href="http://docs.python.org/3.1/reference/datamodel.html#object.__str__" target="_blank">str(x)</a>

<code>x.__str__()</code>

位元組數組的“非正式”值

<code>bytes(x)</code>

<code>x.__bytes__()</code>

格式化字元串的值

<code>format(x, format_spec)</code>

<a href="http://docs.python.org/3.1/reference/datamodel.html#object.__format__" target="_blank">x.__format__(format_spec)</a>

按照約定 <code>__repr__()</code> 方法所傳回的字元串為合法的 Python 表達式。

在調用 <code>print(x)</code> 的同時也調用了 <code>__str__()</code> 方法。

由于 <code>bytes</code> 類型的引入而從 Python 3 開始出現。

周遊某個序列

<code>iter(seq)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__iter__" target="_blank">seq.__iter__()</a>

從疊代器中擷取下一個值

<code>next(seq)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__next__" target="_blank">seq.__next__()</a>

按逆序建立一個疊代器

<code>reversed(seq)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__reversed__" target="_blank">seq.__reversed__()</a>

無論何時建立疊代器都将調用 <code>__iter__()</code> 方法。這是用初始值對疊代器進行初始化的絕佳之處。

無論何時從疊代器中擷取下一個值都将調用 <code>__next__()</code> 方法。

<code>__reversed__()</code> 方法并不常用。它以一個現有序列為參數并将該序列中所有元素從尾到頭以逆序排列生成一個新的疊代器。

擷取一個計算屬性無條件的

<code>x.my_property</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__getattribute__" target="_blank">x.__getattribute__('my_property')</a>

擷取一個計算屬性後備

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__getattr__" target="_blank">x.__getattr__('my_property')</a>

設定某屬性

<code>x.my_property = value</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__setattr__" target="_blank">x.__setattr__('my_property',value)</a>

删除某屬性

<code>del x.my_property</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__delattr__" target="_blank">x.__delattr__('my_property')</a>

列出所有屬性和方法

<code>dir(x)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__dir__" target="_blank">x.__dir__()</a>

如果某個類定義了 <code>__getattribute__()</code> 方法在 每次引用屬性或方法名稱時 Python 都調用它特殊方法名稱除外因為那樣将會導緻讨厭的無限循環。

如果某個類定義了 <code>__getattr__()</code> 方法Python 将隻在正常的位置查詢屬性時才會調用它。如果執行個體 x 定義了屬性color <code>x.color</code> 将 不會 調用<code>x.__getattr__('color')</code>而隻會傳回x.color 已定義好的值。

無論何時給屬性指派都會調用 <code>__setattr__()</code> 方法。

無論何時删除一個屬性都将調用 <code>__delattr__()</code> 方法。

如果定義了 <code>__getattr__()</code> 或 <code>__getattribute__()</code> 方法 <code>__dir__()</code> 方法将非常有用。通常調用 <code>dir(x)</code> 将隻顯示正常的屬性和方法。如果<code>__getattr()__</code>方法動态處理color 屬性 <code>dir(x)</code> 将不會将 color 列為可用屬性。可通過覆寫 <code>__dir__()</code> 方法允許将 color 列為可用屬性對于想使用你的類但卻不想深入其内部的人來說該方法非常有益。

序列的長度

<code>len(seq)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__len__" target="_blank">seq.__len__()</a>

了解某序列是否包含特定的值

<code>x in seq</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__contains__" target="_blank">seq.__contains__(x)</a>

通過鍵來擷取值

<code>x[key]</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__getitem__" target="_blank">x.__getitem__(key)</a>

通過鍵來設定值

<code>x[key] = value</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__setitem__" target="_blank">x.__setitem__(key,value)</a>

删除一個鍵值對

<code>del x[key]</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__delitem__" target="_blank">x.__delitem__(key)</a>

為缺失鍵提供預設值

<code>x[nonexistent_key]</code>

<a href="http://docs.python.org/3.1/library/collections.html#collections.defaultdict.__missing__" target="_blank">x.__missing__(nonexistent_key)</a>

我将此内容從前一節中拿出來使其單獨成節是因為“比較”操作并不局限于數字。許多資料類型都可以進行比較——字元串、清單甚至字典。如果要建立自己的類且對象之間的比較有意義可以使用下面的特殊方法來實作比較。

相等

<code>x == y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__eq__" target="_blank">x.__eq__(y)</a>

不相等

<code>x != y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__ne__" target="_blank">x.__ne__(y)</a>

小于

<code>x &lt; y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__lt__" target="_blank">x.__lt__(y)</a>

小于或等于

<code>x &lt;= y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__le__" target="_blank">x.__le__(y)</a>

大于

<code>x &gt; y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__gt__" target="_blank">x.__gt__(y)</a>

大于或等于

<code>x &gt;= y</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__ge__" target="_blank">x.__ge__(y)</a>

布爾上上下文環境中的真值

<code>if x:</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__bool__" target="_blank">x.__bool__()</a>

自定義對象的複制

<code>copy.copy(x)</code>

<a href="http://docs.python.org/3.1/library/copy.html" target="_blank">x.__copy__()</a>

自定義對象的深度複制

<code>copy.deepcopy(x)</code>

<a href="http://docs.python.org/3.1/library/copy.html" target="_blank">x.__deepcopy__()</a>

在 pickling 之前擷取對象的狀态

<code>pickle.dump(x, file)</code>

<a href="http://docs.python.org/3.1/library/pickle.html#pickle-state" target="_blank">x.__getstate__()</a>

序列化某對象

<a href="http://docs.python.org/3.1/library/pickle.html#pickling-class-instances" target="_blank">x.__reduce__()</a>

序列化某對象新 pickling 協定

<code>pickle.dump(x, file, protocol_version)</code>

<a href="http://docs.python.org/3.1/library/pickle.html#pickling-class-instances" target="_blank">x.__reduce_ex__(protocol_version)</a>

*

控制 unpickling 過程中對象的建立方式

<code>x = pickle.load(file)</code>

<a href="http://docs.python.org/3.1/library/pickle.html#pickling-class-instances" target="_blank">x.__getnewargs__()</a>

在 unpickling 之後還原對象的狀态

<a href="http://docs.python.org/3.1/library/pickle.html#pickle-state" target="_blank">x.__setstate__()</a>

* 要重建序列化對象Python 需要建立一個和被序列化的對象看起來一樣的新對象然後設定新對象的所有屬性。<code>__getnewargs__()</code> 方法控制新對象的建立過程而 <code>__setstate__()</code> 方法控制屬性值的還原方式。

在進入 <code>with</code> 語塊時進行一些特别操作

<code>with x:</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__enter__" target="_blank">x.__enter__()</a>

在退出 <code>with</code> 語塊時進行一些特别操作

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__exit__" target="_blank">x.__exit__()</a>

該檔案對象同時定義了一個 <code>__enter__()</code> 和一個 <code>__exit__()</code> 方法。該 <code>__enter__()</code> 方法檢查檔案是否處于打開狀态如果沒有 <code>_checkClosed()</code>方法引發一個例外。

<code>__enter__()</code> 方法将始終傳回 self —— 這是 <code>with</code> 語塊将用于調用屬性和方法的對象

在 <code>with</code> 語塊結束後檔案對象将自動關閉。怎麼做到的在 <code>__exit__()</code> 方法中調用了 <code>self.close()</code> .

真正神奇的東西

如果知道自己在幹什麼你幾乎可以完全控制類是如何比較的、屬性如何定義以及類的子類是何種類型。

類構造器

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__new__" target="_blank">x.__new__()</a>

類析構器

<code>del x</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__del__" target="_blank">x.__del__()</a>

隻定義特定集合的某些屬性

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__slots__" target="_blank">x.__slots__()</a>

自定義散列值

<code>hash(x)</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__hash__" target="_blank">x.__hash__()</a>

擷取某個屬性的值

<code>x.color</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__get__" target="_blank">type(x).__dict__['color'].__get__(x, type(x))</a>

設定某個屬性的值

<code>x.color = 'PapayaWhip'</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__set__" target="_blank">type(x).__dict__['color'].__set__(x, 'PapayaWhip')</a>

删除某個屬性

<code>del x.color</code>

<a href="http://www.python.org/doc/3.1/reference/datamodel.html#object.__delete__" target="_blank">type(x).__dict__['color'].__del__(x)</a>

控制某個對象是否是該對象的執行個體 your class

<code>isinstance(x, MyClass)</code>

<a href="http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass" target="_blank">MyClass.__instancecheck__(x)</a>

控制某個類是否是該類的子類

<code>issubclass(C, MyClass)</code>

<a href="http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass" target="_blank">MyClass.__subclasscheck__(C)</a>

控制某個類是否是該抽象基類的子類

<code>issubclass(C, MyABC)</code>

<a href="http://docs.python.org/3.1/library/abc.html#abc.ABCMeta.__subclasshook__" target="_blank">MyABC.__subclasshook__(C)</a>

python中以雙下劃線的是一些系統定義得名稱讓python以更優雅得文法實行一些操作本質上還是一些函數和變量與其他函數和變量無二。

比如x.__add__(y) 等價于 x+y

有一些很常見有一些可能比較偏在這裡羅列一下做個筆記備忘。

x.__contains__(y) 等價于 y in x, 在list,str, dict,set等容器中有這個函數

__base__, __bases__, __mro__, 關于類繼承和函數查找路徑的。

class.__subclasses__(), 傳回子類清單

x.__call__(...) == x(...)

x.__cmp__(y) == cmp(x,y)

x.__getattribute__('name') == x.name == getattr(x, 'name'),  比__getattr__更早調用

x.__hash__() == hash(x)

x.__sizeof__(), x在記憶體中的位元組數, x為class得話 就應該是x.__basicsize__

x.__delattr__('name') == del x.name

__dictoffset__ attribute tells you the offset to where you find the pointer to the __dict__ object in any instance object that has one. It is in bytes.

__flags__, 傳回一串數字用來判斷該類型能否被序列化if it's a heap type), __flags__ &amp; 512

S.__format__, 有些類有用

x.__getitem__(y) == x[y], 相應還有__setitem__, 某些不可修改類型如setstr沒有__setitem__

x.__getslice__(i, j) == x[i:j], 有個疑問x='123456789', x[::2],是咋實作得

__subclasscheck__(), check if a class is subclass

__instancecheck__(), check if an object is an instance

__itemsize__, These fields allow calculating the size in bytes of instances of the type. 0是可變長度 非0則是固定長度

x.__mod__(y) == x%y, x.__rmod__(y) == y%x

x.__module__ , x所屬子產品

x.__mul__(y) == x*y,  x.__rmul__(y) == y*x

__reduce__, __reduce_ex__ , for pickle

__slots__ 使用之後類變成靜态一樣沒有了__dict__, 執行個體也不可新添加屬性

__getattr__ 在一般的查找屬性查找不到之後會調用此函數

__setattr__ 取代一般的指派操作如果有此函數會調用此函數 如想調用正常指派途徑用 object.__setattr__(self, name, value)

__delattr__ 同__setattr__, 在del obj.name有意義時會調用

本文轉自 AltBoy 51CTO部落格,原文連結:http://blog.51cto.com/altboy/1945781