Üç nokta nesnesi ne yapar?


539

Ad alanında boşuna gezinirken, adlandırılan garip görünümlü bir nesne fark ettim Ellipsis, özel bir şey gibi görünmüyor veya görünmüyor, ancak küresel olarak mevcut bir yerleşik.

Bir aramadan sonra Numpy ve Scipy tarafından dilimleme sözdiziminin bazı belirsiz varyantlarında kullanıldığını gördüm ... ama neredeyse başka bir şey yok.

Bu nesne dile özel olarak Numpy + Scipy'yi desteklemek için eklendi mi? Elipsin genel bir anlamı veya kullanımı var mı?

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


19
Ben şöyle buldum: x=[];x.append(x);print(x)Döngüsel nesneleri dizgi nasıl ele görmek için girdim . Geri döndü [[...]]. "Ben yazarsam ne olur acaba [[...]]? Tahminim bir sözdizimi hatası atacak mıydı. Bunun yerine geri döndü [[Ellipsis]]. Python çok garip. Bu Google araması beni bu sayfaya getirdi.
Cyoce

22
unutmayın ...bir özyinelemeli repr sadece bir yer tutucudur ve hiçbir ilişkisi olmayan birEllipsis
eevee

16
Tamamen yan bir notta, içe aktarmadaki üçlü nokta "iki paketten yukarı aktar" anlamına gelir.
Mad Physicist

1
@croq stackoverflow.com/q/32395926/2988730 . stackoverflow.com/q/1054271/2988730 . Bu ikisi cevaplarda dokümanlar ve PEP'e uygun bağlantılar ile her şeyi açıklamalıdır.
Mad Physicist

Yanıtlar:


557

Bu son zamanlarda başka bir soru ortaya çıktı . Oradan cevabımı ayrıntılı olarak açıklayacağım :

Üç nokta , dilim gösterimlerinde görünebilen bir nesnedir. Örneğin:

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

Onun yorumu tamamen __getitem__işlevi uygulayan ve Ellipsisorada nesneleri gören şeylere bağlıdır, ancak ana (ve amaçlanan) kullanımı, çok boyutlu bir dizi türü ekleyen numpy üçüncü taraf kitaplığındadır. Birden fazla boyut olduğundan, dilimleme bir başlangıç ​​ve bitiş dizininden daha karmaşık hale gelir; çoklu boyutlarda dilimlemek de yararlıdır. Örneğin, bir 4x4 dizisi verildiğinde, sol üst alan dilim tarafından tanımlanır [: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]])

Bunu daha da genişleten burada, belirtilmeyen dizi boyutlarının geri kalanı için bir yer tutucuyu belirtmek için burada üç nokta kullanılır. Tam dilim işaret olarak düşünün [:]yani 3d dizisi için, bu yerleştirildiği aralık tüm boyutlar için a[...,0]aynı gibidir a[:,:,0], ve 4d'de için a[:,:,:,0], benzer şekilde, a[0,...,0]bir a[0,:,:,0]tam sayı kadar orta yapmak Ancak birçok nokta üst üste ile ( dizideki boyutların).

İlginç bir şekilde, python3'te, Ellipsis literal ( ...) dilim sözdiziminin dışında kullanılabilir, böylece gerçekten yazabilirsiniz:

>>> ...
Ellipsis

Çeşitli sayısal türler dışında, hayır, kullanıldığını sanmıyorum. Bildiğim kadarıyla, sadece numpy kullanımı için eklendi ve nesneyi ve karşılık gelen sözdizimini sağlamak dışında çekirdek desteği yok. Oradaki nesne buna ihtiyaç duymadı, ancak dilimler için gerçek "..." desteği gerektirdi.


22
ayrıca saplama dosyalarında PEP484 tipi ipucunda kullanılır
noɥʇʎԀʎzɐɹƆ

24
Herkesin merak etmesi durumunda: standart kütüphane typingmodülünde de kullanılır : örn Callable[..., int]. intİmzayı belirtmeden dönen bir çağrıyı belirtmek veya Tuple[str, ...]değişken uzunlukta homojen dizeleri belirtmek için.
Anakhand

6
FYI, (şimdi python 3.6+ için) FastAPI çerçevesi de kullanıyor (şimdi). fastapi.tiangolo.com/tutorial/query-params-str-validations
Andrew Allaire

2
@ArtOfWarfare tamamen haklısınız ve bu, cümleler arasında takip etmek yerine sözel olarak "üç nokta" yazan birinden geliyor.
PrimeRibeyeDeal

Bunu buldum. Bir listede kendi kendine referans (dairesel referans) yaptığınızda görünmektedir: a = [1, 2]; a[0] = a; print(a)verir [[...], 2]. Bu aynı şey mi yoksa farklı bir kullanım mı?
Bill

220

Python 3'te, Üç nokta değişmezini ...kod için “nop” yer tutucusu olarak kullanabilirsiniz :

def will_do_something():
    ...

Bu sihir değil ; herhangi bir ifade yerine kullanılabilir ..., örneğin:

def will_do_something():
    1

(“Yaptırım” kelimesini kullanamıyorum, ancak bu kullanımın Guido tarafından açıkça reddedilmediğini söyleyebilirim .)


181
Yarım bir toplantıda, ...insanların daha sonra doldurmak istedikleri bir şeyi belirtmek istedikleri yerlerde ('yapılacak' boş bir blok) ve passkod içermeyen bir blok anlamına gelir.
Gareth Latty

26
Python NotImplemented, tamamlanmamış işlevinizin anlamlı bir şey döndürmesini istediğinizde ( Noneörneğin örneğiniz yerine) yararlıdır . (Başka bir kullanım alanı: Aritmetik işlemlerin uygulanması )
zvyn

13
@zvyn Bu bir gerçek değildir. Bu sadece bir isim. Örneğin NotImplemented = 'something_else'geçerli bir python, ancak ... = 'something_else'bir sözdizimi hatasıdır.
wim

4
@zvyn Ya bu modülü alırken bir istisna oluşursa? :)
pizzapants184

7
@zvyn NotImplementediçin bir alternatif olması amaçlanmamıştır None. Kullanımı oldukça dardır. Buradaki
hans

69

Python 3.5 ve PEP484'ten itibaren değişmez üç nokta, yazma modülünü kullanırken belirli türleri statik tip denetleyicisine göstermek için kullanılır .

Örnek 1:

Rastgele uzunluktaki homojen tupüller, örneğin bir tip ve üç nokta kullanılarak ifade edilebilir Tuple[int, ...]

Örnek 2:

Bağımsız değişkenler için değişmez bir üç nokta (üç nokta) değiştirerek çağrı imzasını belirtmeden çağrılabilir bir dönüş türünü bildirmek mümkündür:

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

46

Üç nokta'yı beklenen doctest çıktısını belirtirken de kullanabilirsiniz :

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
Ama bu aslında Üç Nokta nesnesini içeriyor mu? Bu sadece doctest ayrıştırıcısının / eşleştiricisinin bir özelliği değil mi?
akaihola

1
@akaihola Bunu doctest.ELLIPSIS'te açıklandığı gibi söyleyebilirim . Tüm kullanımları olmasa da ...çoğunun sözdizimsel olmasını ve usegerçek üç nokta nesnesinin olmamasını bekliyorum . Uyarlanabilir bir konsept için gerçekten kullanışlı bir isimden başka bir şey değil mi?
nealmcb

34

Gönderen Python belgelerinde :

Bu nesne genellikle dilimleme ile kullanılır (bkz. Dilimler ). Hiçbir özel işlemi desteklemez. Elips (tam ad) adında tam olarak bir üç elips nesnesi vardır. type(Ellipsis)()Elips tekli üretir.

EllipsisVeya olarak yazılır ....


25

Başkalarının söylediklerini özetlemek gerekirse, Python 3'ten itibaren, Elipsis esasen benzer None, ancak belirli bir kullanım amacı olmayan başka bir tekli sabittir . Mevcut kullanımlar şunları içerir:

  • Kalan boyutlarda tam dilimi temsil etmek için dilim sözdiziminde
  • Bir türün ( Callable[..., int]veya Tuple[str, ...]) yalnızca bir bölümünü belirtmek için tür ipucunda
  • Tür saptama dosyalarında, belirtmeden varsayılan bir değer olduğunu belirtin

Olası kullanımlar şunları içerebilir:

  • NoneGeçerli bir seçenek olan yerler için varsayılan değer olarak
  • Henüz uygulamadığınız bir işlevin içeriği olarak

14

__getitem__...özel sınıfta minimal örnek

Sihirli sözdizimi özel bir sınıfta ...iletildiğinde [], __getitem__()bir Ellipsissınıf nesnesi alır .

Daha sonra sınıf bu Singleton nesnesiyle ne isterse yapabilir.

Misal:

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 yerleşik listsınıfı, ona bir aralığın anlamsallığını vermeyi seçer ve bunun herhangi bir aklı başında kullanımı da elbette olmalıdır.

Şahsen, API'larımda bundan uzak durur ve bunun yerine ayrı, daha açık bir yöntem oluştururdum.

Python 3.5.2 ve 2.7.12'de test edilmiştir.


bunu -O argümanıyla çalıştırın ve kodunuz her zaman çalışır; D
moshevi


7

@ NoɥʇʎԀʎzɐɹƆ ve @phoenix tarafından belirtildiği gibi - Gerçekten saplama dosyalarında kullanabilirsiniz. Örneğin

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

Bu üç nokta hakkında daha fazla bilgi ve örnek burada bulunabilir https://www.python.org/dev/peps/pep-0484/#stub-files


2

Amaçlanan kullanımı sadece bu üçüncü taraf modülleri için olmamalıdır. Python belgelerinde doğru şekilde belirtilmemiş (ya da belki de bulamadım) ama üç nokta ...aslında CPython'da en az bir yerde kullanılıyor.

Python'da sonsuz veri yapılarını temsil etmek için kullanılır. Listelerle oynarken bu gösterime geldim.

Daha fazla bilgi için bu soruya bakın .


8
Farklı şeyler: Bu soru ellipsisyerleşik tip ve Ellipsisnesne hakkında sorular sorar . Eliplerle sonsuz veri yapılarını temsil etmek, yalnızca ellipsistür veya Ellipsisnesne ile hiçbir ilgisi olmayan gösterim içindir .
chys

3
@chys Aslında, küçük bir şekilde yapar - Python __repr__dizeleri geçerli Python ifadeleri olmayı amaçlamaktadır - eğer dilde olduğu gibi elips şeklinde olmasaydı, temsil geçerli bir ifade olmazdı.
Gareth Latty

3
@Lattyware Orijinal tasarımın tasarladığı doğru. Aynı zamanda eval(repr(a))amacı da eşit olmayı amaçlamaktadır a. Ne yazık ki, yerleşik türler için bile uygulamada zaman zaman yanlıştır. Şuna deneyin: a=[]; a.append(a); eval(repr(a)). repr(a), [[...]]Python 2'de geçersiz ifade. (Python 3'te geçerlidir, ancak değerlendirme sonucu orijinal niyetin aksine farklı bir şeydir.)
chys

1

Bu eşdeğerdir.

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

...içinde tanımlanan bir sabittir built-in constants.

eksilti

Üç nokta harfi harfiyle aynı “...”. Kullanıcı tarafından tanımlanan kap veri türleri için çoğunlukla genişletilmiş dilimleme sözdizimi ile birlikte kullanılan özel değer.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.