วัตถุ Ellipsis ทำอะไร


539

ในขณะที่ท่องไปใน namespace อย่างเฉื่อยชาฉันสังเกตเห็นวัตถุแปลก ๆ ที่เรียกว่าEllipsisดูเหมือนจะไม่เป็นหรือทำอะไรเป็นพิเศษ แต่มันมีอยู่ทั่วโลกในตัว

หลังจากการค้นหาฉันพบว่ามันถูกใช้ในตัวแปรที่ไม่ชัดเจนของไวยากรณ์การแบ่งโดย Numpy และ Scipy ... แต่แทบไม่มีอะไรอื่น

มีการเพิ่มวัตถุนี้ในภาษาเพื่อรองรับ Numpy + Scipy หรือไม่ Ellipsis มีความหมายทั่วไปหรือใช้งานเลย

D:\workspace\numpy>python
Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Ellipsis
Ellipsis

ดูคำตอบสำหรับstackoverflow.com/questions/752602/…
Patrick McElhaney

19
ฉันพบสิ่งนี้: ฉันเข้ามาx=[];x.append(x);print(x)เพื่อดูว่ามันจัดการกับวัตถุวัฏจักรสตริงอย่างไร [[...]]มันกลับมา ฉันคิดว่า "ฉันสงสัยว่าจะเกิดอะไรขึ้นถ้าฉันพิมพ์[[...]]ฉันเดาว่ามันจะทำให้เกิดข้อผิดพลาดทางไวยากรณ์ แต่มันกลับมา[[Ellipsis]]แล้ว Python แปลกมากการค้นหาของ Google ที่นำฉันมาที่หน้านี้
Cyoce

22
โปรดทราบว่าการพิมพ์...ซ้ำแบบเรียกซ้ำเป็นเพียงตัวยึดตำแหน่งและไม่มีความเกี่ยวข้องกับEllipsis
Eevee

16
ในหมายเหตุด้านทั้งหมดทริปเปิลจุดในการนำเข้าหมายถึง "นำเข้าจากสองแพ็คเกจขึ้นไป"
นักฟิสิกส์บ้า

1
@croq stackoverflow.com/q/32395926/2988730 stackoverflow.com/q/1054271/2988730 ทั้งสองควรอธิบายทุกอย่างพร้อมลิงก์ไปยังเอกสารและ PEP ที่เหมาะสมในคำตอบ
นักฟิสิกส์บ้า

คำตอบ:


557

เรื่องนี้เกิดขึ้นในคำถามอื่นเมื่อเร็ว ๆ นี้ ฉันจะทำอย่างละเอียดในคำตอบของฉันจากที่นั่น:

จุดไข่ปลาเป็นวัตถุที่สามารถปรากฏในสัญกรณ์ชิ้น ตัวอย่างเช่น:

myList[1:2, ..., 0]

การแปลความหมายของมันคืออย่างหมดจดถึงการดำเนินการใด__getitem__ฟังก์ชั่นและเห็นEllipsisวัตถุมี แต่หลัก (และเจตนา) การใช้งานอยู่ในnumpyห้องสมุดของบุคคลที่สามซึ่งจะเพิ่มประเภทอาร์เรย์หลายมิติ เนื่องจากมีมากกว่าหนึ่งมิติการแบ่งส่วนจะซับซ้อนกว่าเพียงดัชนีเริ่มต้นและหยุด มันมีประโยชน์ที่จะสามารถเชือดในหลายมิติได้เช่นกัน เช่นกำหนดอาร์เรย์ 4x4 พื้นที่ด้านบนซ้ายจะถูกกำหนดโดยชิ้น[:2,:2]:

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

>>> a[:2,:2]  # top left
array([[1, 2],
       [5, 6]])

การขยายเพิ่มเติมนี้ Ellipsis จะใช้ที่นี่เพื่อระบุตัวแทนสำหรับส่วนที่เหลือของขนาดอาร์เรย์ที่ไม่ได้ระบุ คิดว่ามันเป็นการแสดงชิ้นเต็ม[:]สำหรับมิติทั้งหมดในช่องว่างที่วางไว้ดังนั้นสำหรับอาร์เรย์ 3 มิติa[...,0]เป็นเช่นเดียวกับa[:,:,0]และสำหรับ 4d a[:,:,:,0]ในทำนองเดียวกันa[0,...,0]คือa[0,:,:,0](ด้วยอย่างไรก็ตามหลาย ๆ colons ที่อยู่ตรงกลางทำขึ้นเต็มจำนวน ของมิติข้อมูลในอาร์เรย์)

ที่น่าสนใจใน python3 ตัวอักษร Ellipsis ( ...) นั้นสามารถใช้งานได้นอกไวยากรณ์ชิ้นดังนั้นคุณสามารถเขียนได้จริง:

>>> ...
Ellipsis

นอกเหนือจากประเภทตัวเลขต่าง ๆ ไม่ฉันไม่คิดว่ามันจะใช้ เท่าที่ฉันทราบมันได้รับการเพิ่มอย่างหมดจดสำหรับการใช้งานแบบไม่มีผู้อื่นและไม่มีการสนับสนุนหลักนอกเหนือจากการให้วัตถุและไวยากรณ์ที่เกี่ยวข้อง วัตถุที่อยู่ที่นั่นไม่ต้องการสิ่งนี้ แต่การสนับสนุน "... " ตามตัวอักษรสำหรับส่วนต่างๆ


22
มันยังใช้ในการบอกประเภท PEP484 ในไฟล์ stub
noɥʇʎԀʎzɐɹƆ

24
ในกรณีที่มีใครอยากรู้อยากเห็น: มันยังใช้ในtypingโมดูลไลบรารีมาตรฐานเช่นCallable[..., int]เพื่อระบุ callable ที่ส่งกลับintโดยไม่ระบุลายเซ็นหรือTuple[str, ...]เพื่อระบุ tuple ที่มีความยาวเหมือนกันของตัวแปร
Anakhand

6
FYI, กรอบ FastAPI (ซึ่งใช้สำหรับ python 3.6+) เช่นกัน (ตอนนี้) ใช้ fastapi.tiangolo.com/tutorial/query-params-str-validations
Andrew Allaire

2
@ ArtOfWarfare คุณพูดถูกและนี่มาจากใครบางคนที่พูดว่า "จุดไข่ปลา" โดยใช้วาจาแทนการลากเส้นระหว่างประโยค
PrimeRibeyeDeal

ฉันพบสิ่งนี้ มันดูเหมือนว่าจะปรากฏเมื่อคุณทำการอ้างอิงตนเอง (อ้างอิงแบบวงกลม) ในรายการ: ให้a = [1, 2]; a[0] = a; print(a) [[...], 2]สิ่งนี้เป็นสิ่งเดียวกันหรือแตกต่างกันหรือไม่?
ตั๋ว

220

ใน Python 3 คุณสามารถใช้ตัวอักษร Ellipsis ...เป็นตัวยึด“ nop” สำหรับรหัส:

def will_do_something():
    ...

นี่ไม่ใช่เวทมนต์ การแสดงออกใด ๆ สามารถนำมาใช้แทน...เช่น:

def will_do_something():
    1

(ไม่สามารถใช้คำว่า "ถูกทำนองคลองธรรม" แต่ฉันสามารถพูดได้ว่าการใช้งานนี้ไม่ได้ถูกปฏิเสธโดยกุยโด้)


181
ในการประชุมครึ่งครั้งฉันมักจะเห็นการ...ใช้ที่ผู้คนต้องการระบุสิ่งที่พวกเขาต้องการกรอกในภายหลัง (บล็อกว่าง 'todo') และpassหมายถึงบล็อกที่ไม่มีรหัส
Gareth Latty

26
Python มีNotImplementedตัวอักษรซึ่งมีประโยชน์เมื่อคุณต้องการให้ฟังก์ชันที่ไม่สมบูรณ์ของคุณส่งคืนสิ่งที่มีความหมาย (แทนที่จะNoneเป็นในตัวอย่างของคุณ) (USECASE อื่น ๆ : การดำเนินการดำเนินการทางคณิตศาสตร์ )
zvyn

13
@zvyn นั่นไม่ใช่ตัวอักษร มันเป็นเพียงชื่อ ตัวอย่างเช่นNotImplemented = 'something_else'python ที่ถูกต้อง แต่... = 'something_else'เป็นข้อผิดพลาดทางไวยากรณ์
Wim

4
@zvyn จะเกิดอะไรขึ้นถ้ามีข้อยกเว้นเกิดขึ้นขณะนำเข้าโมดูลนั้น :)
pizzapants184

7
@zvyn ไม่ได้มีวัตถุประสงค์ที่จะเป็นทางเลือกที่จะNotImplemented Noneการใช้งานค่อนข้างแคบ ดูเอกสารที่นี่
hans

69

ในฐานะของ Python 3.5 และPEP484จุดไข่ปลาตัวอักษรจะใช้เพื่อแสดงถึงประเภทบางประเภทให้กับตัวตรวจสอบชนิดคงที่เมื่อใช้โมดูลการพิมพ์

ตัวอย่างที่ 1:

ตัวอย่างที่เป็นเนื้อเดียวกันความยาวโดยพลการสามารถแสดงได้โดยใช้ชนิดเดียวและจุดไข่ปลา Tuple[int, ...]

ตัวอย่างที่ 2:

มีความเป็นไปได้ที่จะประกาศชนิดส่งคืนของ callable โดยไม่ระบุลายเซ็นการโทรโดยการแทนที่จุดไข่ปลาแท้จริง (สามจุด) สำหรับรายการอาร์กิวเมนต์:

def partial(func: Callable[..., str], *args) -> Callable[..., str]:
    # Body

46

คุณยังสามารถใช้ Ellipsis เมื่อระบุเอาต์พุตdoctest ที่คาดไว้:

class MyClass(object):
    """Example of a doctest Ellipsis

    >>> thing = MyClass()
    >>> # Match <class '__main__.MyClass'> and <class '%(module).MyClass'>
    >>> type(thing)           # doctest:+ELLIPSIS
    <class '....MyClass'>
    """
    pass

9
แต่สิ่งนี้เกี่ยวข้องกับวัตถุ Ellipsis จริงหรือไม่? มันไม่ใช่แค่คุณสมบัติของเครื่องมือแยกวิเคราะห์ / จับคู่คำสอน?
akaihola

1
@akaihola ผมบอกว่ามันไม่ได้ตามที่อธิบายไว้ในdoctest.ELLIPSIS ฉันคาดหวังว่าส่วนใหญ่ถ้าไม่ใช่การใช้ทั้งหมด...เป็นวากยสัมพันธ์และไม่ใช่useวัตถุ Ellipsis จริง มันไม่มีอะไรมากไปกว่าชื่อที่มีประโยชน์สำหรับแนวคิดที่ปรับเปลี่ยนได้
nealmcb

34

จากเอกสาร Python :

วัตถุนี้ใช้กันทั่วไปโดยการหั่น (ดูตัวแบ่งส่วนข้อมูล ) มันไม่สนับสนุนการปฏิบัติการพิเศษ มีหนึ่งจุดไข่ปลาวัตถุชื่อ Ellipsis (ชื่อในตัว) type(Ellipsis)()ผลิต Ellipsis singleton

มันเป็นเรื่องที่เขียนเป็นหรือEllipsis...


25

การสรุปสิ่งที่คนอื่นพูดในขณะที่ Python 3 Ellipsis นั้นเป็นค่าคงตัวเดี่ยวอื่น ๆ ที่คล้ายกันNoneแต่ไม่มีการใช้งานโดยเฉพาะ การใช้งานที่มีอยู่รวมถึง:

  • ในไวยากรณ์ชิ้นเพื่อแสดงชิ้นเต็มในมิติที่เหลือ
  • ในการบอกใบ้ประเภทเพื่อระบุเพียงส่วนหนึ่งของประเภท ( Callable[..., int]หรือTuple[str, ...] )
  • ในประเภทไฟล์ stub เพื่อระบุว่ามีค่าเริ่มต้นโดยไม่ระบุ

การใช้งานที่เป็นไปได้ ได้แก่ :

  • เป็นค่าเริ่มต้นสำหรับสถานที่ที่Noneเป็นตัวเลือกที่ถูกต้อง
  • ในฐานะที่เป็นเนื้อหาสำหรับฟังก์ชั่นที่คุณยังไม่ได้ใช้งาน

14

__getitem__...ตัวอย่างที่น้อยที่สุดในคลาสที่กำหนดเอง

เมื่อไวยากรณ์เวทมนตร์...ถูกส่งผ่านไปยัง[]คลาสที่กำหนดเองให้__getitem__()รับEllipsisคลาสอ็อบเจ็กต์

ชั้นเรียนสามารถทำสิ่งใดก็ได้ตามที่ต้องการด้วยวัตถุ Singleton นี้

ตัวอย่าง:

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# Ellipsis notation generates the Ellipsis class object.
# Ellipsis is a singleton, so we can compare with `is`.
assert C()[...] is Ellipsis

# Everything mixed up.
assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)

Python ในตัว listคลาสเลือกที่จะให้มันมีความหมายของช่วงและการใช้สติใด ๆ ของมันควรจะเกินไปแน่นอน

โดยส่วนตัวแล้วฉันจะอยู่ห่างจากมันใน API ของฉันและสร้างวิธีแยกต่างหากที่ชัดเจนกว่าแทน

ทดสอบใน Python 3.5.2 และ 2.7.12


เรียกใช้ด้วยอาร์กิวเมนต์-Oและรหัสของคุณจะทำงานเสมอ D
moshevi

12

คุณสามารถใช้ Ellipsis ด้วยตัวคุณเองในสถานการณ์การแบ่งส่วนที่กำหนดเองอย่างที่ numpy ได้ทำไปแล้ว แต่มันไม่มีการใช้งานในคลาสบิวอินใด ๆ

ฉันไม่รู้ว่ามันถูกเพิ่มเข้ามาเพื่อใช้ใน numpy โดยเฉพาะหรือไม่ แต่ฉันไม่เคยเห็นมันใช้ในที่อื่น

ดูเพิ่มเติม: คุณใช้ไวยากรณ์การตัดจุดไข่ปลาใน Python ได้อย่างไร


7

ดังที่ได้กล่าวไว้โดย @ noɥʇʎԀʎzɐɹƆและ @phoenix - คุณสามารถใช้มันในไฟล์ stub ได้ เช่น

class Foo:
    bar: Any = ...
    def __init__(self, name: str=...) -> None: ...

ข้อมูลเพิ่มเติมและตัวอย่างของวิธีใช้จุดไข่ปลานี้สามารถดูได้ที่นี่https://www.python.org/dev/peps/pep-0484/#stub-files


2

การใช้งานตามวัตถุประสงค์ไม่ควรมีไว้สำหรับโมดูลบุคคลที่สามเหล่านี้เท่านั้น มันไม่ได้กล่าวถึงอย่างถูกต้องในเอกสาร Python (หรือบางทีฉันไม่สามารถหาได้) แต่จุดไข่ปลา...นั้นใช้ใน CPythonอย่างน้อยในที่เดียว

มันถูกใช้สำหรับการแสดงโครงสร้างข้อมูลที่ไม่มีที่สิ้นสุดใน Python ฉันมาถึงสัญลักษณ์นี้ในขณะที่เล่นกับรายการ

ดูคำถามนี้สำหรับข้อมูลเพิ่มเติม


8
สิ่งต่าง ๆ คำถามนี้ถามเกี่ยวกับellipsisชนิดในตัวและEllipsisวัตถุ การแสดงโครงสร้างข้อมูลที่ไม่สิ้นสุดด้วยจุดไข่ปลานั้นเป็นการแสดงอย่างหมดจดโดยไม่เกี่ยวข้องกับellipsisชนิดหรือEllipsisวัตถุ
chys

3
@chys ที่จริงแล้วมันมีขนาดเล็ก - __repr__สตริงPython มุ่งหวังที่จะเป็นสำนวน Python ที่ถูกต้อง - หากไม่ใช่สำหรับจุดไข่ปลาที่มีอยู่ในภาษาเช่นเดียวกับมันการเป็นตัวแทนจะไม่ใช่การแสดงออกที่ถูกต้อง
Gareth Latty

3
@ Lattyware ก็จริงการออกแบบดั้งเดิมตั้งใจ นอกจากนี้ยังมีความตั้งใจมุ่งมั่นที่จะเท่ากับeval(repr(a)) aน่าเสียดายที่มันผิดพลาดเป็นครั้งคราวแม้แต่ในตัวเครื่อง a=[]; a.append(a); eval(repr(a))ลองนี้: repr(a)คือ[[...]]นิพจน์ที่ไม่ถูกต้องใน Python 2 (ใน Python 3 ใช้ได้ แต่ผลลัพธ์ของการประเมินนั้นแตกต่างออกไปซึ่งยังคงตรงกันข้ามกับความตั้งใจดั้งเดิม)
chys

1

สิ่งนี้เทียบเท่า

l=[..., 1,2,3]
l=[Ellipsis, 1,2,3]

...built-in constantsเป็นภายในคงที่ที่กำหนดไว้

การตัดคำทิ้งจากประโยด

เช่นเดียวกับเครื่องหมายจุดไข่ปลา“ ... ” ค่าพิเศษที่ใช้ส่วนใหญ่ร่วมกับไวยากรณ์การแบ่งส่วนเพิ่มสำหรับชนิดข้อมูลคอนเทนเนอร์ที่ผู้ใช้กำหนด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.