Python內建函式(二)

veelion發表於2019-01-15

本節繼續講述更多的Python的內建函式。

內建函式

IO操作

input([prompt])
如果存在 prompt 實參,則將其寫入標準輸出,末尾不帶換行符。接下來,該函式從輸入中讀取一行,將其轉換為字串(除了末尾的換行符)並返回。當讀取到 EOF 時,則觸發 EOFError。例如:

In [25]: s = input('>>')
>>猿人學python

In [26]: s
Out[26]: '猿人學python'

如果載入了 readline 模組,input() 將使用它來提供複雜的行編輯和歷史記錄功能。

open(file, mode=’r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
開啟 file 並返回對應的 file object。如果該檔案不能開啟,則觸發 OSError。

file 是一個 path-like object,表示將要開啟的檔案的路徑(絕對路徑或者當前工作目錄的相對路徑),也可以是要被封裝的整數型別檔案描述符。(如果是檔案描述符,它會隨著返回的 I/O 物件關閉而關閉,除非 closefd 被設為 False 。)

mode 是一個可選字串,用於指定開啟檔案的模式。預設值是 ‘r’ ,這意味著它以文字模式開啟並讀取。其他常見模式有:寫入 ‘w’ (截斷已經存在的檔案);排它性建立 ‘x’ ;追加寫 ‘a’ (在 一些 Unix 系統上,無論當前的檔案指標在什麼位置,所有 寫入都會追加到檔案末尾)。在文字模式,如果 encoding 沒有指定,則根據平臺來決定使用的編碼:使用 locale.getpreferredencoding(False) 來獲取本地編碼。(要讀取和寫入原始位元組,請使用二進位制模式並不要指定 encoding。)可用的模式有:

字元 意義
‘r’ 讀取(預設)
‘w’ 寫入,並先截斷檔案
‘x’ 排它性建立,如果檔案已存在則失敗
‘a’ 寫入,如果檔案存在則在末尾追加
‘b’ 二進位制模式
‘t’ 文字模式(預設)
‘+’ 更新磁碟檔案(讀取並寫入)
‘U’ universal newlines 模式(已棄用)
預設的模式是 ‘r’ (開啟並讀取文字,同 ‘rt’ )。對於二進位制寫入, ‘w+b’ 模式開啟並把檔案截斷成 0 位元組; ‘r+b’ 則不會截斷。

正如在 Overview 中提到的,Python區分二進位制和文字I/O。以二進位制模式開啟的檔案(包括 mode 引數中的 ‘b’ )返回的內容為 bytes物件,不進行任何解碼。在文字模式下(預設情況下,或者在 *mode* 引數中包含‘t’` )時,檔案內容返回為 str ,首先使用指定的 encoding (如果給定)或者使用平臺預設的的位元組編碼解碼。

註解 Python不依賴於底層作業系統的文字檔案概念;所有處理都由Python本身完成,因此與平臺無關。
buffering 是一個可選的整數,用於設定緩衝策略。傳遞0以切換緩衝關閉(僅允許在二進位制模式下),1選擇行緩衝(僅在文字模式下可用),並且>1的整數以指示固定大小的塊緩衝區的大小(以位元組為單位)。如果沒有給出 buffering 引數,則預設緩衝策略的工作方式如下:

二進位制檔案以固定大小的塊進行緩衝;使用啟發式方法選擇緩衝區的大小,嘗試確定底層裝置的“塊大小”或使用 io.DEFAULT_BUFFER_SIZE。在許多系統上,緩衝區的長度通常為4096或8192位元組。
“互動式”文字檔案( isatty() 返回 True 的檔案)使用行緩衝。其他文字檔案使用上述策略用於二進位制檔案。
encoding 是用於解碼或編碼檔案的編碼的名稱。這應該只在文字模式下使用。預設編碼是依賴於平臺的(不 管 locale.getpreferredencoding() 返回何值),但可以使用任何Python支援的 text encoding 。有關支援的編碼列表,請參閱 codecs 模組。

errors 是一個可選的字串引數,用於指定如何處理編碼和解碼錯誤 – 這不能在二進位制模式下使用。可以使用各種標準錯誤處理程式(列在 Error Handlers ),但是使用 codecs.register_error() 註冊的任何錯誤處理名稱也是有效的。標準名稱包括:

如果存在編碼錯誤,’strict’ 會引發 ValueError 異常。 預設值 None 具有相同的效果。
‘ignore’ 忽略錯誤。請注意,忽略編碼錯誤可能會導致資料丟失。
‘replace’ 會將替換標記(例如 ‘?’ )插入有錯誤資料的地方。
‘surrogateescape’ 將表示任何不正確的位元組作為Unicode專用區中的程式碼點,範圍從U+DC80到U+DCFF。當在寫入資料時使用 surrogateescape 錯誤處理程式時,這些私有程式碼點將被轉回到相同的位元組中。這對於處理未知編碼的檔案很有用。
只有在寫入檔案時才支援 ‘xmlcharrefreplace’。編碼不支援的字元將替換為相應的XML字元引用 &#nnn;。
‘backslashreplace’ 用Python的反向轉義序列替換格式錯誤的資料。
‘namereplace’ (也只在編寫時支援)用 \N{…} 轉義序列替換不支援的字元。
newline 控制 universal newlines 模式如何生效(它僅適用於文字模式)。它可以是 None,”,’\n’,’\r’ 和 ‘\r\n’。它的工作原理:

從流中讀取輸入時,如果 newline 為 None,則啟用通用換行模式。輸入中的行可以以 ‘\n’,’\r’ 或 ‘\r\n’ 結尾,這些行被翻譯成 ‘\n’ 在返回呼叫者之前。如果它是 ”,則啟用通用換行模式,但行結尾將返回給呼叫者未翻譯。如果它具有任何其他合法值,則輸入行僅由給定字串終止,並且行結尾將返回給未呼叫的呼叫者。
將輸出寫入流時,如果 newline 為 None,則寫入的任何 ‘\n’ 字元都將轉換為系統預設行分隔符 os.linesep。如果 newline 是 ” 或 ‘\n’,則不進行翻譯。如果 newline 是任何其他合法值,則寫入的任何 ‘\n’ 字元將被轉換為給定的字串。
如果 closefd 是 False 並且給出了檔案描述符而不是檔名,那麼當檔案關閉時,底層檔案描述符將保持開啟狀態。如果給出檔名則 closefd 必須為 True (預設值),否則將引發錯誤。

可以通過傳遞可呼叫的 opener 來使用自定義開啟器。然後通過使用引數( file,flags )呼叫 opener 獲得檔案物件的基礎檔案描述符。 opener 必須返回一個開啟的檔案描述符(使用 os.open as opener 時與傳遞 None 的效果相同)。

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
列印objects到文字流file,以分隔符sep分隔多個物件,並以end結尾。

語法相關

breakpoint(*args, **kwargs)
此函式會在呼叫時將你陷入偵錯程式中。具體來說,它呼叫 sys.breakpointhook(),直接傳遞 argskws 。預設情況下, sys.breakpointhook() 呼叫 pdb.set_trace()且沒有引數。在這種情況下,它純粹是一個便利函式,因此您不必顯式匯入 pdb 且鍵入儘可能少的程式碼即可進入偵錯程式。但是, sys.breakpointhook() 可以設定為其他一些函式並被 breakpoint() 自動呼叫,以允許進入你想用的偵錯程式。

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
將 source 編譯成程式碼或 AST 物件。程式碼物件可以被 exec() 或 eval() 執行。source 可以是常規的字串、位元組字串,或者 AST 物件。

ascii(object)
返回一個只用ASCII碼錶示的物件。類似函式repr()返回一個物件的可列印字串表示,但是會把其中非ASCII的字元用\x, \u, \U進行轉義。比如:

In [23]: ascii([1,2,3])
Out[23]: '[1, 2, 3]'

In [24]: ascii('程式設計')
Out[24]: "'\\u7f16\\u7a0b'"

In [25]: ascii('a\nb')
Out[25]: "'a\\nb'"

repr(object)
返回包含物件的可列印表示的字串。對於許多型別,此函式嘗試返回一個字串,該字串在傳遞給eval()時會產生具有相同值的物件,否則表示形式是一個用尖括號括起來的字串,它包含物件型別的名稱附加資訊通常包括物件的名稱和地址。 類可以通過定義repr()方法來控制此函式為其例項返回的內容。

In [54]: repr({'a': 1, 'b':2, 'c':3})
Out[54]: "{'a': 1, 'b': 2, 'c': 3}"

In [55]: s = repr({'a': 1, 'b':2, 'c':3})

In [56]: eval(s)
Out[56]: {'a': 1, 'b': 2, 'c': 3}

eval(expression, globals=None, locals=None)
實參是一個字串,以及可選的 globals 和 locals。globals 實參必須是一個字典。locals 可以是任何對映物件。
這個函式也可以用來執行任何程式碼物件(如 compile() 建立的)。這種情況下,引數是程式碼物件,而不是字串。如果編譯該物件時的 mode 實參是 ‘exec’ 那麼 eval() 返回值為 None 。

In [17]: a = 2

In [18]: eval('a+2')
Out[18]: 4

In [19]: eval('3*3')
Out[19]: 9

In [20]: d = ascii({'a':1, 'b':2})

In [21]: d
Out[21]: "{'a': 1, 'b': 2}"

In [22]: eval(d)
Out[22]: {'a': 1, 'b': 2}

提示: exec() 函式支援動態執行語句。 globals() 和 locals() 函式各自返回當前的全域性和本地字典,因此您可以將它們傳遞給 eval() 或 exec() 來使用。

exec(object[, globals[, locals]])
這個函式支援動態執行 Python 程式碼。object 必須是字串或者程式碼物件。如果是字串,那麼該字串將被解析為一系列 Python 語句並執行(除非發生語法錯誤)。[1] 如果是程式碼物件,它將被直接執行。在任何情況下,被執行的程式碼都需要和檔案輸入一樣是有效的(見參考手冊中關於檔案輸入的章節)。請注意即使在傳遞給 exec() 函式的程式碼的上下文中,return 和 yield 語句也不能在函式定義之外使用。該函式返回值是 None 。

In [24]: exec('a=2;x=a*3;print(x)')
6

globals()
返回表示當前全域性符號表的字典。這總是當前模組的字典(在函式或方法中,不是呼叫它的模組,而是定義它的模組)。

locals()
更新並返回表示當前本地符號表的字典。在函式塊而不是類塊中呼叫 locals() 時會返回自由變數。

註解 不要更改此字典的內容;更改不會影響直譯器使用的區域性變數或自由變數的值。

help([object])
啟動內建的幫助系統(此函式主要在互動式中使用)。如果沒有實參,直譯器控制檯裡會啟動互動式幫助系統。如果實參是一個字串,則在模組、函式、類、方法、關鍵字或文件主題中搜尋該字串,並在控制檯上列印幫助資訊。如果實參是其他任意物件,則會生成該物件的幫助頁。

該函式通過 site 模組加入到內建名稱空間。

memoryview(obj)
返回由給定實參建立的“記憶體檢視”物件。有關詳細資訊,請參閱 Memory Views。

類相關

@classmethod
把一個方法封裝成類方法。

一個類方法把類自己作為第一個實參,就像一個例項方法把例項自己作為第一個實參。請用以下習慣來宣告類方法:

class A:
    @classmethod
    def func(cls, arg1, ...): ...

@classmethod形式是函式裝飾器。
它可以同時在類(如 C.f())和例項(如 C().f())上呼叫。例項除了它的類資訊,其他都會被忽略。如果一個類方法在子類上呼叫,子類會作為第一個實參傳入。

類方法和 C++ 和 Java 的靜態方法是有區別的。如果你想要靜態方法,請看 staticmethod()。

@staticmethod

將方法轉換為靜態方法。
靜態方法不會接收隱式的第一個引數。要宣告一個靜態方法,請使用此語法

class A:
    @staticmethod
    def func(arg1, arg2, ...): ...

@staticmethod 形式函式是一個 decorator 函式。它可以在類(例如 C.f() )或例項(例如 C().f() )上呼叫。例項會被忽略,只需要類本身。

Python中的靜態方法與Java或C ++中的靜態方法類似。另請參閱 classmethod() ,用於建立備用類建構函式的變體。

像所有裝飾器一樣,也可以像常規函式一樣呼叫 staticmethod ,並對其結果執行某些操作。比如某些情況下需要從類主體引用函式並且您希望避免自動轉換為例項方法。對於這些情況,請使用此語法:

class A:
    buildin_open = staticmethod(open)

issubclass(class, classinfo)
如果 class 是 classinfo 的子類(直接、間接或 虛擬 的),則返回 true。classinfo 可以是類物件的元組,此時 classinfo 中的每個元素都會被檢查。其他情況,會觸發 TypeError 異常。

class property(fget=None, fset=None, fdel=None, doc=None)
返回 property 屬性。

fget 是獲取屬性值的函式。 fset 是用於設定屬性值的函式。 fdel 是用於刪除屬性值的函式。並且 doc 為屬性物件建立文件字串。

一個典型的用法是定義一個託管屬性 x:

class A:
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x

    def setx(self, value):
        self._x = value

    def delx(self):
        del self._x

    x = property(getx, setx, delx, "I'm the 'x' property.")

如果 a 是 A 的例項,a.x 將呼叫getter,a.x = value 將呼叫setter, del a.x 將呼叫deleter。

如果提供了doc引數,則它就是這個屬性的docstring。否則,這個屬性會拷貝fget的docstring。

通過裝飾器可以輕鬆實現可讀屬性:

class Point:
    def __init__(self):
        self._x = 0
        self._y = 0

    @property
    def x(self):
        """Get the current x"""
        return self._x

裝飾器@property把方法x()變為一個“getter”只讀的同名屬性,並把x的docstring“Get the current x”作為屬性的docstring。

屬性物件具有可用作裝飾器的getter,setter和deleter方法,這些方法建立屬性的副本,並將相應的訪問器函式設定為裝飾函式。參考下面的例子:

class A:
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

這段程式碼與第一個示例完全等效。 要保證其他函式指定與原始屬性相同的名稱(在本例中為x)。

返回的屬性物件還具有與建構函式引數對應的屬性fget,fset和fdel。

Python 3.5版更改:屬性物件的docstring現在可寫了。

super([type[, object-or-type]])

返回將方法呼叫委託給父類或兄弟類型別的代理物件。這對於訪問已在類中重寫的繼承方法很有用。搜尋順序與getattr()使用的搜尋順序相同,只是跳過了型別本身。

該型別的mro屬性列出了getattr()和super()使用的方法解析搜尋順序。該屬性是動態的,只要更新繼承層次結構,就可以更改該屬性。

如果省略第二個引數,則返回的超級物件是未繫結的。如果第二個引數是一個物件,則isinstance(obj,type)必須為true。如果第二個引數是一個型別,則issubclass(type2,type)必須為true(這對於classmethods很有用)。

super有兩個典型的用例。在具有單繼承的類層次結構中,super可用於引用父類而不顯式命名它們,從而使程式碼更易於維護。這種用法與其他程式語言中super的使用密切相關。

第二個用例是在動態執行環境中支援協作多重繼承。此用例是Python獨有的,在靜態編譯語言或僅支援單繼承的語言中找不到。這使得實現“菱形圖”成為可能,其中多個基類實現相同的方法。好的設計要求此方法在每種情況下都具有相同的呼叫簽名(因為呼叫的順序是在執行時確定的,因為該順序適應類層次結構中的更改,並且因為該順序可以包括在執行時之前未知的兄弟類)。

對於這兩種用例,典型的超類呼叫如下所示:

class B(A):
    def method(self, arg):
        super().method(arg) # 相當於:super(B, self).method(arg)

注意,super()是作為顯式點狀屬性查詢的繫結過程的一部分實現的,例如super().getitem(name)。它通過實現自己的getattribute()方法來實現,它以可預測的順序搜尋類,支援協作多重繼承。 因此,對於使用語句或運算子(如super()[name])進行隱式查詢,未定義super()。

另外請注意,除零引數形式外,super()不限於使用內部方法。 兩個引數形式完全指定引數並進行適當的引用。零引數形式僅適用於類定義,因為編譯器填寫必要的細節以正確檢索正在定義的類,以及訪問普通方法的當前例項。

物件操作

callable(object)
如果實參 object 是可呼叫的,返回 True,否則返回 False。如果返回真,呼叫仍可能會失敗;但如果返回假,則呼叫 object 肯定會失敗。注意類是可呼叫的(呼叫類會返回一個新的例項)。如果例項的類有 call() 方法,則它是可呼叫。

delattr(object, name)
setattr() 相關的函式。實參是一個物件和一個字串。該字串必須是物件的某個屬性。如果物件允許,該函式將刪除指定的屬性。例如 delattr(x, ‘foobar’) 等價於 del x.foobar 。

dir([object])
如果沒有實參,則返回當前本地作用域中的名稱列表。如果有實參,它會嘗試返回該物件的有效屬性列表。

如果物件有一個名為 dir() 的方法,那麼該方法將被呼叫,並且必須返回一個屬性列表。這允許實現自定義 getattr() 或 getattribute() 函式的物件能夠自定義 dir() 來報告它們的屬性。

如果物件不提供 dir(),這個函式會嘗試從物件已定義的 dict 屬性和型別物件收集資訊。結果列表並不總是完整的,如果物件有自定義 getattr(),那結果可能不準確。

預設的 dir() 機制對不同型別的物件行為不同,它會試圖返回最相關而不是最全的資訊:

  • 如果物件是模組物件,則列表包含模組的屬性名稱。
  • 如果物件是型別或類物件,則列表包含它們的屬性名稱,並且遞迴查詢所有基類的屬性。
  • 否則,列表包含物件的屬性名稱,它的類屬性名稱,並且遞迴查詢它的類的所有基類的屬性。

返回的列表按字母表排序。

getattr(object, name[, default])
返回物件命名屬性的值。name 必須是字串。如果該字串是物件的屬性之一,則返回該屬性的值。例如, getattr(x, ‘foobar’) 等同於 x.foobar。如果指定的屬性不存在,且提供了 default 值,則返回它,否則觸發 AttributeError。

setattr(object, name, value)
它是getattr()的對應函式。實參是物件,字串和任意值。字串可能是已存在或新增屬性的名稱。該函式把value賦值給屬性。例如,setattr(x, 'foobar', 123)相當於x.foobar = 123

hasattr(object, name)
該實參是一個物件和一個字串。如果字串是物件的屬性之一的名稱,則返回 True,否則返回 False。(此功能是通過呼叫 getattr(object, name) 看是否有 AttributeError 異常來實現的。)

hash(object)
返回該物件的雜湊值(如果它有的話)。雜湊值是整數。它們在字典查詢元素時用來快速比較字典的鍵。相同大小的數字變數有相同的雜湊值(即使它們型別不同,如 1 和 1.0)。

註釋: 如果物件實現了自己的 hash() 方法,請注意,hash() 根據機器的字長來截斷返回值。另請參閱 hash()。

id(object)
返回物件的“標識值”。該值是一個整數,在此物件的生命週期中保證是唯一且恆定的。兩個生命期不重疊的物件可能具有相同的 id() 值。

isinstance(object, classinfo)
如果 object 實參是 classinfo 實參的例項,或者是(直接、間接或 虛擬)子類的例項,則返回 true。如果 object 不是給定型別的物件,函式始終返回 false。如果 classinfo 是物件型別(或多個遞迴元組)的元組,如果 object 是其中的任何一個的例項則返回 true。 如果 classinfo 既不是型別,也不是型別元組或型別的遞迴元組,那麼會觸發 TypeError 異常。

len(s)
返回物件的長度(元素個數)。實參可以是序列(如 string、bytes、tuple、list 或 range 等)或集合(如 dictionary、set 或 frozen set 等)。

vars([object])

返回具有dict屬性的模組,類,例項或任何其他物件的dict屬性。

模組和例項等物件具有可更新的dict屬性; 但是,其他物件可能對其dict屬性具有寫入限制(例如,類使用types.MappingProxyType來防止直接字典更新)。

沒有引數,vars()就像locals()一樣。 請注意,locals字典僅對讀取有用,因為忽略了對locals字典的更新。

總結

Python的內建函式提供了常用的功能,熟練使用這些內建函式對程式設計有很大幫助。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章