Python 3.8

Tegnap kiadásra került a Python 3.8

Az újdonságokról itt lehet olvasni.

Az egyik legnagyobb újításként, kibővítésre került a nyelv szintaxisa a "nevesített kifejezés" szerkezetével ("Assignment Expressions" vagy "Named Expressions"); az eredeti javaslat itt található.

A kifejezést az := ún. rozmár ("walrus") operátorral hozhatjuk létre. Megfelelő használatával lerövidíthetjük a futási időt, de ugyanakkor javasolt, hogy csak indokolható esetben, mértékkel alkalmazzuk, elkerülendő a nehezen olvasható kódok létrehozását.

Néhány példa:


Lista létrehozását korábban, sok számolásra késztetve a gépet, 
megtehettük (bután) így:

    [sin(10), sin(10)**2, sin(10)/3]

    vagy okosan:

    y= sin(10)
    [y, y**2, y/3]

    most így is eljárhatunk:
     
    [y := sin(10), y**2, y/3]

    
    Még izgalmasabb, ha listaépítő kifejezésben vesszük igénybe 
    az új értékadást:

    [ (y := sin(x), y**2) for x in range(45) ]

    és bevethejük a feltételvizsgálatnál is:
    
    [(y, y**2) for i in range(10) if (y := randrange(1,100)) % 5 ]


A lambda függvényeknél a "hagyományos" értékadás nincs megengedve, 
de a nevesített kifejezés igen. Az alábbi példában egy kételemű 
sokaságot (tuple-t) adunk vissza:

    f=lambda t: ((y := sin(t)), 2*y*cos(t))
    

Szótár létrehozása:

    { (n := randrange(1,100)):str(n) for i in range(10) }

    Mivel a kulcs kerül előbb kiértékelésre, ezért az a szótárérték
    előállításához felhasználható.


A nevesített kifejezés hatóköre nem szorítkozik az objektumépítő 
kifejezés "belsejére":

    [ (i,y) for i in range(30) if (y := i)%3 ]

    >>> i
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'i' is not defined
    >>> y
    29

    Figyelem! Ha a listaépítő kifejezés előtt volt már egy 'y' változónk,
    akkor az felülíródik!
    
    A kiszélesített hatókör jól hasznosítható az any() és az all() esetében:

    >>> text="""1. sor
    ... #2. sor
    ... 3. sör
    ... #4.sor"""
    
    >>> any( (comm1 := line).startswith("#") for line in text.splitlines() )
    True
    >>> comm1
    '#2. sor'
    
    >>> all( (failed := line).endswith("sor") for line in text.splitlines() )
    False
    >>> failed
    '3. sör'

Hozzászólások

Egyszer nagyon régen nekiálltam kígyós nyelven programozni, azóta nagyon sok szintaktikai elemmel bővült a nyelv. Szerintem már túl lett bonyolítva.

Ez pont hasznos. Nagyjabol ugy mukodik, mint a C-s ertekadas, aminek az eredmenye is egy ertek, es tovabbi valtozoknak ertekul adhato, vagy feltetelben felhasznalhato. C-ben ezt ki is szoktak hasznalni.

--
When you tear out a man's tongue, you are not proving him a liar, you're only telling the world that you fear what he might say. -George R.R. Martin

Talán nem mondanám, hogy túl lett bonyolítva, de értem mire gondolsz. Érdekes kérdés, hogy egy programozási nyelvet, de akár egy tetszőleges rendszert, kell-e folyamatosan fejleszteni. Vajon a végtelenségig lehetséges új és értelmes jellemzőket beleintegrálni, vagy egyszer hátra lehet dőlni, hogy most már minden készen van?

Szerencsére a szintaxis csak kibővült, tehát aki nem ismerkedik meg az új lehetőségekkel, az továbbra is nyugodtan programozhat úgy, mint eddig.

--
eutlantis

"Érdekes kérdés, hogy egy programozási nyelvet, de akár egy tetszőleges rendszert, kell-e folyamatosan fejleszteni."

Egy olyan általános felhasználású nyelvet, mint a Python, folyamatosan kell fejleszteni, ahogy változik a világ, pl. a sok magos CPU-k általánossá válása nyomán (asyncio és társai). Jönnek újabb absztrakciók, ahogy felmerül az igény rájuk, és folyamatosan változik, hogy ma épp mi tekinthető alacsony szintű nyelvnek. Ha változik a hardver, változnak a nyelvek is. Kíváncsi leszek pl. hogy ha megjelennek a gyors fázisváltó memóriák, és nem lesz külön háttértár és RAM, az hogyan változtatja majd meg a rendszereket.

Igazad lehet. Ha a procik erősebbek, akkor talán a programozási paradigmák is jobban eltolódnak a funkcionális nyelvi elemek használata felé.

A gyors fázisváltó memória, az a memristor lenne?
Az is olyan, mint a fúziós reaktor, bármikor kérdezel rá, hogy mikor lesz készen, mindig 50 évet mondanak, erre meg talán tízet.

--
eutlantis

Hát mi azt várjuk, hogy a céges belső compiler végre átálljon python 3.x-re, mert 2.7-ben olyan hackelések, meg hátulról vakarjuk a fülenk megoldások vannak, hogy sírok mindig, amikor a kódbázisra nézek. :DDD
--
"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." John F. Woods

Ahogy én látom így kívülről, mivel a BASIC-ben nincs külön értékadó és egyenlőségvizsgáló operátor, ezért a Python-ba se tettek eredetileg, mindkettőre az =egyelőségjel szolgált.

Most feltalálták az értékadáshoz a := operátort, öröm, boldogság.

Valós használati eset (nem-Pythonos szintaxissal):


while ((actrec:=FetchNextItem()!=NULL) {
...
}

Nem tudom melyik Python verziót említed, mert amióta én ismerem a nyelvet, az összehasonlító operátor a ==.
A := pedig nem "általános" értékadó utasítás (mint a Pascalban), az továbbra is az egyes =.
Például ez így érvénytelen:
>> y:=10
de lehet erőltetni (bár minek):
>>(y:=10)

--
eutlantis

Az eredeti értékadó utasítást nem lehet minden helyzetben alkalmazni, mert így elkerülhető sok, az elírásból származó hiba. Például a C-ben gyakran előfordul:


Ezt akartuk leírni:
  if(a==strlen(s)){}

de ezt követtük el:
  if(a=strlen(s)){}

A Pythonban ezért az "if" után nem lehet értékadás, 
tehát ez szintaktikai hibát eredményez:
  if a=len(s):

ez a helyes:
  if a==len(s):

és most már ezt is lehet:
  if (b := a)==len(s):

A második példád is ugyanezért hibás szintaktikailag, 
mert elírás révén származtatható lenne ebből:
  [y == sin(10), y**2, y/3]

--
eutlantis

és most már ezt is lehet:
if (b := a)==len(s):

Ez pontosan mit is jelent?
Akkor igaz, ha "b" legyen egyelő "a" -val és így "b" egyenlő az "s" lista elemszámával?

Ezzel mit nyert? Bizonyos esetekben gyorsul a végrehajtás? Mert, hogy a forrás olvashatóbb (=érthetőbb) nem lesz, az biztos.

Gyakorlatilag ezt váltotta ki?

b = a
if b == len(s):

Nem az if-ben van jelentősége, hanem egy ciklusfeltételben:


while (x:= NextRec())!=NULL:

Tulajdonképpen ez egy alternatív értékadó-operátor, de az túl egyszerű lett volna, ha csak annyit csinálnak, hogy 'mostantól a := is használható értékadás értelmeben', inkább kitalálták, hogy a két értékadó operátor más-más kontextuális inspirációt tartalmaz, ezért spéci ellenőrzések vannak, hogy a használatukat korlátozzák.


a=b # jó
a:=b # nem jó
(a=b) # nem jó
(a:=b) # jó

...a két értékadó operátor más-más kontextuális inspirációt tartalmaz, ezért spéci ellenőrzések vannak, hogy a használatukat korlátozzák.

Igen, hogy elejét vegyék az elírásból eredően hibás, de futtatható kód létrehozásának.

...de az túl egyszerű lett volna,...

Feltételezem, hogy a javaslatod szerint eljárni nem lett volna olyan egyszerű; de a nyelvi formalizmusnak nem vagyok szakértője.
Én csak használom a kalapácsot, és ugyan már jó ideje, de a kalapácskészítés minden csínját-bínját nem ismerem; azonban ez az új kiegészítés nagyon kézre áll:-)

--
eutlantis

Szeretem a Pytont, teszik benne sok minden. De emlékszem, anno a Perl azért ment ki a divatból, mert túl könnyű volt benne teljesen olvashatatlan kódot alkotni. Szerintem szegény Pythonra is ez a sors vár, ahogy a fenti példák közül több is igen jól illusztrálja.

--
Csaba