溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中Ellipsis對象有什么用

發(fā)布時間:2021-07-10 16:22:46 來源:億速云 閱讀:177 作者:Leah 欄目:編程語言

本篇文章為大家展示了Python中Ellipsis對象有什么用,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

什么是Ellipsis

在 Python 中你可能有時候會看到一個奇怪的用法,就像是這樣:

>>> ...  Ellipsis

在你輸入了三個點之后,Python 解釋器非但不會報錯,反而還會返回給你「Ellipsis」這么一個信息。那么這個有趣的東西是什么呢?

查閱 Python 官方文檔后可以看到,它是一個**「內置常量」**(Built-in Constant)。經常用于對用戶自定義的容器數(shù)據類型進行切片用法的擴展。

這也就意味著它可能是會作為一個「小眾且另類」的語法糖來使用,但如果你用于 Python 中的容器數(shù)據類型(比如列表)進行切片索引時,可能會引發(fā)錯誤:

>>> nums = list(range(10))  >>> nums  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  >>> nums[...]  Traceback (most recent call last):    File "<stdin>", line 1, in <module>  TypeError: list indices must be integers or slices, not ellipsis

除此之外,如果你使用的是 Python 2 的解釋器,那么壓根就不支持 Ellipsis 的用法,從一開始輸入時就報錯:

$ python2  WARNING: Python 2.7 is not recommended.   This version is included in macOS for compatibility with legacy software.   Future versions of macOS will not include Python 2.7.   Instead, it is recommended that you transition to using 'python3' from within Terminal.  Python 2.7.16 (default, Nov  9 2019, 05:55:08)   [GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.32.4) (-macos10.15-objc-s on darwin  Type "help", "copyright", "credits" or "license" for more information.  >>> ...    File "<stdin>", line 1      ...      ^  SyntaxError: invalid syntax

雖然說在列表中使用 Ellipsis 會報錯,但是碰到這種情況你會發(fā)現(xiàn)解釋器返回給你的是這樣的東西:

>>> nums = [1,2,3]  >>> nums  [1, 2, 3]  >>> nums[1] = nums  >>> nums  [1, [...], 3]

可以看到,這里我們將 nums 中的第二個元素替換成自身,就會形成不斷地遞歸嵌套賦值,而解釋器最后直接給出了頭尾兩個元素之外,其他全部元素都會被 ... 所囊括在內。

根據 Python 官方的另一處文檔,Ellipsis 本身也不支持任何操作,僅僅只是一個單例對象(Singleton)

誰能想到,Guido van Rossum 這么一位被人稱為「仁慈的獨裁者」的 Python 之父采納 Ellipsis 的原因竟然是因為:有人認為三個省略號的寫法可愛。(原文為:「Some folks thought it would be cute to be able to write incomplete code like this」)

應用

要說這個看起來「雞肋」的 Ellipsis 類型對象沒有用,這個說法似乎也不正確。因為它作為一種奇怪的語法糖也被應用到了某些地方。

Numpy 中的切片

雖然官方說 Ellipsis 主要用于用戶自定義容器類型的切片操作,但是在我搜索了許久之后發(fā)現(xiàn)用 Ellipsis 來實現(xiàn)所謂的切片操作的貌似只有 Numpy。

使用 Python 做數(shù)據分析、挖掘或機器學習相關的朋友一定對 Numpy 高性能的科學計算庫并不陌生。在 Numpy 中我們真正的使用 Ellipsis 來進行切片索引:

>>> import numpy as np  >>> arr = np.arange(9).reshape((3,3))  >>> arr  array([[0, 1, 2],         [3, 4, 5],         [6, 7, 8]])

需要注意的是,Ellipsis 主要是對二維以上的數(shù)組才起作用:

>>> arr[...,1:2]  array([[1],         [4],         [7]])  >>> arr[2, ...]  array([6, 7, 8])

從結果中我們看到,Ellipsis 三個省略號的寫法其實就等價于 arr[:, 1:2] 冒號的寫法。但是在使用過程中 Ellipsis 只能出現(xiàn)一次:

>>> ndarr = np.arange(24).reshape((2,3,4))  >>> ndarr  array([[[ 0,  1,  2,  3],          [ 4,  5,  6,  7],          [ 8,  9, 10, 11]],         [[12, 13, 14, 15],          [16, 17, 18, 19],          [20, 21, 22, 23]]])  >>> ndarr[:, :, :]  array([[[ 0,  1,  2,  3],          [ 4,  5,  6,  7],          [ 8,  9, 10, 11]],         [[12, 13, 14, 15],          [16, 17, 18, 19],          [20, 21, 22, 23]]])  >>> ndarr[..., ..., ...]  Traceback (most recent call last):    File "<stdin>", line 1, in <module>  IndexError: an index can only have a single ellipsis ('...')

Ellipsis 在 Numpy 中出現(xiàn)的意義在于,當你的數(shù)組是高維的數(shù)組時,那么可以直接使用它來作為選取其他維度的等價寫法,以下例子來源于 Numpy 官方文檔:

>>> z = np.arange(81).reshape(3,3,3,3)  >>> z[1,...,2] # 等價于 z[1, :,:, 2]  array([[29, 32, 35],         [38, 41, 44],         [47, 50, 53]])

Type Hint 類型注解

自從 PEP 484 之后,Python 解釋器開始支持類型注解。所謂的類型注解無非就是在 Python 實際代碼中能像注釋那樣對當中的一些參數(shù)或返回值添加類型注釋,就像是這樣:

def add(x: int, y: int) -> int:      return x + y

如果你是有使用過 Java 或者 Go 這類對類型注解要求較為嚴格的編譯型語言,那么相信對此并不陌生,無論是變量還是方法,都要寫上對應的類型以防編譯報錯;但即便沒有接觸過這類編譯型語言也不要緊,將其理解為注釋即可,這樣的注釋是能被編輯器或 IDE 所支持,在你要查看函數(shù)定義或文檔時會給予提示。

但是 Type Hint 僅僅只是一種「協(xié)定」,告訴別人你的方法里參數(shù)是如何、最后返回的是什么僅此而已,無論是加與不加都不會影響最終代碼的效果,影響的僅僅只是代碼的可讀性罷了。

如果你的方法有多個返回值,我們不可能對每個返回值的類型都寫上注解,因此這時 Ellipsis 對象就派上了用場。根據官方文檔給出的說明,我們完全可以像這樣來進行類型注解:

from typing import Tuple  def get_many_value(      a:int, b:int, c:int,       d:int, e:int, f:int  ) -> Tuple[int, ...]:      return [a+b, c+d, e+f]

這樣的寫法本質上就是 *args 的作用,表示同類型的可變長度元組。如果你將 Tuple 換成是 List,那么解釋器會報錯,因為 *args 在方法中的表現(xiàn)就是元組,那么作為注解的 Ellipsis 也應如此。這可能也就說明為什么在 Tuple 注解中不報錯了。

FastAPI 中的必選參數(shù)

目前正流行開來的高性能 Web 框架 FastAPI 中,也應用了 Ellipsis。它用以表示參數(shù)是必填項,這在 Swagger 頁面更能直觀體現(xiàn)。

# pip install fastapi  # pip install uvicorn  from fastapi import FastAPI, Query  app = FastAPI()  @app.get('/greetWithOutEllipsis')  async def greet(name: str = None):      if name:          return {"info": f"Welcome! {name}"}      return {"info": f"Welcome to FastAPI!"}  @app.get('/greetWithEllipsis')  async def greet(name: str = Query(..., min_length=2)):      if name:          return {"info": f"Welcome! {name}"}      return {"info": f"Welcome to FastAPI!"}  if __name__ == "__main__":      import uvicorn      uvicorn.run(app, port = 5000)

啟動服務之后,在瀏覽器中輸入 http://127.0.0.1:5000/docs 便能進入到服務的 Swagger 頁面中,在上述例子中如果 name 參數(shù)并非是個必要的參數(shù)時,在 Swagger 頁面中不會看到任何標識,即便我們不帶上 name 參數(shù)也能進行請求:

Python中Ellipsis對象有什么用

非必要參數(shù)

但當我們加上了一個 Query() 方法,并將其 Ellipsis 對象丟到當中時,不僅會給參數(shù)加上 required 的標識,同時還對傳入的字符串長度進行了限制。

Python中Ellipsis對象有什么用

必要參數(shù)

除了參數(shù)之外,在 FastAPI 中你還可以在請求體、路徑、字段等多個地方使用 Ellipsis 對象。

「偽」 pass 寫法

Ellipsis 有時候還可以作為 pass 的一種「偽」寫法,比如這樣:

def greet():      ... #等價于 pass

上述內容就是Python中Ellipsis對象有什么用,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI