4 мощни функции, които Python все още липсва

Python е жив език - в непрекъснато развитие, за да бъде в крак с времето. Фондацията на Python Software не просто допълва стандартната библиотека и референтната реализация CPython, но също така въвежда нови функции и усъвършенствания на самия език.

Например, Python 3.8 въведе нов синтаксис за вградени задания („моржовият оператор“), който прави някои операции по-кратки. Друго ново одобрено подобрение на синтаксиса, съвпадение на шаблони, ще улесни писането на код, който оценява за един от многото възможни случаи. И двете функции са вдъхновени от тяхното присъствие и полезност на други езици.

И те са само две от множество полезни функции, които могат да бъдат добавени към Python, за да направят езика по-изразителен, по-мощен, по-подходящ за съвременния свят на програмиране. Какво друго бихме могли да си пожелаем? Ето още четири езикови функции, които биха могли да добавят нещо реално на Python - две, които всъщност може да получим, а две вероятно няма. 

Истински константи

Python всъщност няма концепцията за постоянна стойност. Днес константите в Python са предимно въпрос на конвенция. Използването на име, което е в all-caps и snake case - напр., DO_NOT_RESTART - е намек, че променливата е предназначена да бъде константа. По същия начин typing.Final анотацията на  типа дава подсказка за линтери, че обектът не трябва да се модифицира, но не налага това по време на изпълнение.

Защо? Защото изменчивостта е дълбоко вкоренена в поведението на Python. Когато присвоявате стойност на променлива - напр.,  x=3 - създавате име в локалното пространство от имена  xи го насочвате към обект в системата, който има целочислената стойност  3. Python по всяко време предполага, че имената са променливи - че всяко име може да сочи към всеки обект. Това означава, че всеки път, когато се използва име, Python си прави труда да търси какъв обект сочи. Този динамизъм е една от основните причини Python да работи по-бавно от някои други езици. Динамичността на Python предлага голяма гъвкавост и удобство, но това се дължи на производителността по време на изпълнение.

Едно от предимствата на наличието на истински константни декларации в Python би било известно намаляване на честотата на търсене на обекти, които се извършват по време на изпълнение, и по този начин по-добра производителност. Ако изпълнението знае предварително, че дадена стойност никога не се променя, не е необходимо да търси своите обвързвания. Това също може да осигури път за по-нататъшни оптимизации на трети страни, като системи, които генерират машинен код от приложения на Python (Cython, Nuitka).

Истинските константи обаче биха били голяма промяна и най-вероятно обратна несъвместима промяна. Също така ще бъде обсъдено дали константите ще идват чрез нов синтаксис - например все още неизползваният  $ символ - или като разширение на съществуващия начин на Python да декларира имена. И накрая, има по-обширен, философски въпрос дали истинските константи имат смисъл в езика, където динамичността е голяма част от апела.

Накратко, възможно е да видим истински константи в Python, но това би било голяма пробивна промяна.

Истинско претоварване и генерици

На много езици могат да бъдат написани множество версии на една и съща функция за работа с различни видове вход. Например, една  to_string() функция може да има различни реализации за преобразуване от цели числа, числа с плаваща запетая или други обекти - но те ще споделят едно и също име за удобство. „Претоварването“ или „генеричните продукти“ улесняват писането на надежден софтуер, тъй като можете да пишете общи методи за общи процеси, вместо да използвате метод, специфичен за даден тип.

Python ви позволява да използвате едно име на функция, за да свършите работата на много, но не чрез дефиниране на множество екземпляри на функция. Можете да дефинирате име само веднъж в даден обхват и да го свържете само с един обект наведнъж, така че не можете да имате няколко версии на една функция под едно и също име.

Това, което разработчиците на Python обикновено правят, за да заобиколят това, е да използват вградени модули като  isinstance() или за  type() да определят типа на променливата, изпратена на функция, след което да предприемат действия въз основа на типа. Понякога това включва изпращане към специфична за типа версия на функция под капака. Но този подход затруднява други разработчици да разширят функцията ви, освен ако не си направите всичко възможно да я направите разширяема - например чрез изпращане към методи в клас, които могат да бъдат подкласирани.

PEP 3124, усъвършенстван през април 2007 г., предложи механизъм за декориране на функции, за да покаже, че те могат да бъдат претоварени. Предложението беше отложено, вместо да бъде отхвърлено направо - което означава, че идеята беше фундаментално обоснована, но моментът не беше подходящ за изпълнение. Един фактор, който може да ускори приемането на претоварване в Python - или да накара идеята да се откаже изцяло - е внедряването на новопредложената система за съвпадение на шаблони.

На теория, съвпадението на шаблоните може да се използва под капака за справяне с изпращането на претоварване. Въпреки това, модел за съвпадение също може да се прилага като обосновка за не прилагане на генеричните лекарства в Python, тъй като тя вече осигурява елегантен начин да операции диспечерски зависимост от типа на подписи.

Така че един ден може да получим истинско претоварване в Python или предимствата му да бъдат заменени от други механизми.

Оптимизации на рекурсията на опашката

Много езикови компилатори използват оптимизации за рекурсия на опашката, където функциите, които се извикват, не създават нови рамки на стека в приложението и по този начин рискуват да взривят стека, ако работят твърде дълго. Python не прави това и всъщност създателите му постоянно се противопоставят на това.

Една от причините е, че голяма част от Python, отвътре навън, използва  итерация,  а не  рекурсия  - генератори, съпрограми и т.н. В този случай това означава използване на функция с цикъл и структура на стека вместо рекурсивен механизъм. Всяко извикване на цикъла може да бъде запазено в стека, за да се създаде нова рекурсия, и да изскочи от стека, когато рекурсията завърши.

Разработчиците на Python се насърчават да използват тези модели вместо рекурсия, така че изглежда малко надежда за оптимизации на рекурсията. Шансовете тук съвсем не са вероятни, тъй като идиомите на Python поддържат други решения.

Многоредови ламбди

Lambdas, или анонимни функции, го превърнаха в Python само след известна съпротива от страна на създателя на езика Guido van Rossum. Тъй като ламбдите на Python съществуват сега, те са силно ограничени: Те ви позволяват да използвате само един израз (по същество всичко отдясно на знак за равенство в операция за присвояване) като тяло на функцията. Ако искате пълен блок от изявления, просто ги разбийте и направете действителна функция от тях.

Причината се свежда до дизайна на езика, както го вижда Ван Росум. Както ван Росум пише през 2006 г., „намирам за   неприемливо всяко решение, което вгражда базиран на отстъпа блок в средата на израз. Тъй като намирам алтернативния синтаксис за групиране на изрази (напр. Скоби или ключови думи начало / край) еднакво неприемлив, това почти прави многоредова ламбда неразрешим пъзел. "

С други думи, проблемът не е технически, а липсата на синтаксис за многоредови ламбди, който допълва съществуващата естетика на синтаксиса на Python. Вероятно няма начин да се направи това, което да не включва създаване на специален случай, а език, който натрупва специални случаи, обикновено става неприятен за използване. Докато не се появи такъв еднорог, просто ще трябва да се задоволим с отделно дефинирани функции.

Многоредови ламбди вероятно не се случват в Python.

Прочетете повече за Python:

  • Python 3.9: Какво ново и по-добро
  • Най-добрите нови функции в Python 3.8
  • По-добро управление на проекти на Python с поезия
  • Virtualenv и venv: Обяснени са виртуалните среди на Python
  • Python virtualenv и venv правят и не
  • Обяснение на нишките на Python и подпроцесите
  • Как да използвам Python дебъгер
  • Как да използвам timeit за профилиране на Python код
  • Как да използвам cProfile за профилиране на Python код
  • Започнете с async в Python
  • Как да използвам asyncio в Python
  • Как да конвертирате Python в JavaScript (и обратно)
  • Python 2 EOL: Как да оцелеем в края на Python 2
  • 12 Pythons за всяка нужда от програмиране
  • 24 библиотеки на Python за всеки разработчик на Python
  • 7 сладки IDE на Python, които може да сте пропуснали
  • 3 основни недостатъка на Python и техните решения
  • 13 сравнени уеб рамки на Python
  • 4 Тестови рамки на Python, за да смачкате вашите грешки
  • 6 страхотни нови функции на Python, които не искате да пропуснете
  • 5 Python дистрибуции за овладяване на машинно обучение
  • 8 страхотни библиотеки на Python за обработка на естествен език
  • 6 Python библиотеки за паралелна обработка
  • Какво е PyPy? По-бърз Python без болка
  • Какво е Cython? Python със скоростта на C