Jakie są cechy Pythona, które sprawiają, że jest unikalny jako własny język? [Zamknięte]


12

Jakie są cechy Pythona, które sprawiają, że jest unikalny jako własny język? Szukam jakiejkolwiek cechy, od dobrej do złej, przydatnej do utrudniania, składni do użycia w świecie rzeczywistym, ale nieprzejrzyste obserwacje byłyby najbardziej przydatne dla przeciętnego programisty.

Jestem tu nowicjuszem, więc intuicyjne rzeczy mogą wymagać wyjaśnienia .....


9
Python nie jest unikalny, nie zawiera pojedynczej unikalnej funkcji niewidocznej w żadnym innym języku.
SK-logic,

10
To jedyny znany mi język, który nosi imię Monty Pythona ...
yannis

@ SK-logic pytanie dotyczy cech, których cechy są podzestawem. Czy nie ma żadnych cech charakterystycznych dla Pythona?
kojiro

@kojiro, nigdy nie widziałem formalnej definicji „cechy”, więc wolałbym nie zgadywać.
SK-logic,

1
@kojiro, cechy PL są zwykle rozumiane zarówno jako jego składnia, jak i semantyka. I oba są formalnie zdefiniowane.
SK-logic,

Odpowiedzi:


22

Trudno będzie znaleźć funkcje, które są absolutnie wyjątkowe . Większość istniejących funkcji językowych przyjęto w więcej niż jednym języku od ich powstania. Niektóre mogą być rzadsze, głównie dlatego, że albo są nowe i wciąż pozostają w ukryciu, albo wymarły z ważnego powodu. Niemniej jednak nawet wtedy lepiej byłoby spojrzeć na kombinacje funkcji.

To powiedziawszy, kilka funkcji Pythona powinno stanowić stosunkowo unikalną kombinację. Przynajmniej nie znam zdalnie tak popularnych (i praktycznych) języków, które w większości pokrywają się z zestawem funkcji. Jak zauważono w komentarzach, Ruby jest dość blisko, ale istnieją jednak liczne różnice.

  • Metaprogramowanie na podstawie metaklasy . Zasadniczo uruchamianie dowolnego kodu przy tworzeniu klas. Sprawia, że bardzo fajne jest dostosowywanie klas przy bardzo niewielkim nakładzie pracy po stronie odbierającej - np. W przypadku mapowania obiektowo-relacyjnego (ORM), klasy klienta można pisać jak zwykle z kilkoma dodatkowymi liniami, attr = SomeDataType()a tona kodu jest generowana automatycznie. Przykładem tego są „modele” Django .
  • Zachęcamy do korzystania z iteratorów do wszystkiego . Jest to szczególnie widoczne w wersji 3.x, gdzie większość alternatyw opartych na listach z odpowiednikiem opartym na iteratorze została zniesiona na korzyść tego ostatniego. Iteratory służą również jako niemal uniwersalny interfejs dla kolekcji (zarówno tych, które faktycznie masz w pamięci, jak i tych, których potrzebujesz tylko raz, a zatem możesz tworzyć za pomocą poniższych funkcji). Niezależnie od kolekcji, efektywne O(1)przestrzennie ( miejsce na wyniki pośrednie często następuje naturalnie, bardzo niewiele zadań faktycznie potrzebuje wszystkich elementów jednocześnie), kompasowanie danych nigdy nie było łatwiejsze.
  • Wyrażenia generatora związane z powyższym. Wielu słyszało o zrozumieniu listy (tworzenie listy z innej iterowalnej, filtrowanie i mapowanie w tym procesie, z bardzo wygodną składnią). Zapomnij o nich, to cukier składniowy, szczególny przypadek. Wyrażenia generatora są bardzo zbliżone pod względem składniowym i ostatecznie skutkują tą samą sekwencją elementów, ale generują wyniki leniwie (a zatem zajmują O(1)miejsce, chyba że wyraźnie trzymasz wyniki wokół).
  • yield, co sprawia, że ​​pisanie iteratorów (zwanych tutaj generatorami) jest o wiele przyjemniejsze. Są starszym bratem z powyższego, wspierają wszystkie rodzaje kontroli. C # ma coś podobnego, z tym samym słowem kluczowym. Ale yieldjest również przeciążony, aby obsługiwać ograniczony rodzaj korupcji (na przykład Lua ma bardziej rozbudowane wsparcie), który mimo to został dobrze wykorzystany przez mądrych ludzi pracujących nad trudnymi problemami. Dwa przykłady z góry mojej głowy: Analiza rekurencyjnego zejścia z funkcją śledzenia wstecznego i bez limitu stosu oraz asynchroniczne operacje we / wy (z wygodną składnią).
  • Przypisywanie do wielu celów i wielokrotne rozpakowywanie. Przydział na sterydy. Nie tylko możesz przypisywać wiele wartości naraz (nawet w przypadku zamiany wartości i iteracji - for key, value in mapping.items()), możesz rozpakować dowolną iterację o znanej długości (szczerze mówiąc, głównie krotki) do wielu zmiennych. Od 3.x to nawet praktyczne dla zbiorów nieznanej długości jak można określić kilka zmiennych biorąc pojedyncze elementy i jeden podejmowania cokolwiek pozostaje: first, *everything_in_between, last = values.
  • Deskryptory , prawdopodobnie najsilniejsze spośród różnych sposobów dostosowywania dostępu do atrybutów. Istnieją właściwości (jak w języku C #, ale bez obsługi specjalnego języka), metody statyczne, metody klas itp. Zaimplementowane jako deskryptory. Są to również obiekty pierwszej klasy. Zaledwie tydzień temu miałem do czynienia z powtarzalnym i trudnym kodem we właściwościach - napisałem więc małą funkcję generującą powtarzalną część i zawijającą ją w properyobiekt.
  • Zasada czysto spalona (wcięcie do rozgraniczania bloków). To ostatnie celowo stawiam. Chociaż odróżnia Pythona, tak naprawdę nie wyróżnia się w codziennym programowaniu, gdy się do niego przyzwyczaisz (a przynajmniej takie jest moje doświadczenie).

Nadal jestem trochę nowicjuszem w Ruby, ale myślę, że trafia również oprócz ostatniego punktu? Tak czy inaczej zgadzam się, że „unikatowy” prawdopodobnie nie zostanie znaleziony w Pythonie, ale może być „niespotykany wśród innych najpopularniejszych języków”.
Rig

@Rig: Nie jestem ekspertem od Ruby, ale nie widziałem żadnej metaklasy (Ruby z pewnością jest równie potężny w zakresie metaprogramowania i może używać go do podobnych celów, ale miałem wrażenie, że osiągnięto to inaczej), ani generatorów, ani wyrażeń generatora (choć wydaje się, że są to coroutines), ani iterowalne rozpakowywanie (istnieje jednak przypisanie do wielu celów) ani deskryptory w Ruby. Tak, Ruby i Python nakładają się na siebie. Ale są różnice .

Dobrze, +1. Dla mnie „przypisanie do sterydów” jest w rzeczywistości „dopasowaniem wzorców biedaka”, ale jest jednak niezwykle przydatne :) Zauważyłem również, jak elastyczne jest przekazywanie parametrów w funkcjach: *argsi **kwargsbezbolesny sposób mapowania krotek i dykt na parametry itp. ,
9000

Uważam, że wspólne seplenienie z CLOS uderza we wszystkie punkty oprócz użycia składni opartej na układzie. Haskell nie jest obiektowy (chociaż istnieją rozszerzenia OO), ale inny niż punkt metaklasy, uważam, że pasuje do wszystkich tych funkcji.
Jules

3

Wydaje mi się, że jedyną rzeczą, która sprawia, że ​​Python jest wyjątkowy, jest szczególna kombinacja funkcji, które ujawnia. Dotyczy to większości języków programowania.

Lub może być jedna drobna rzecz: nie widziałem sposobu, w jaki Python jawnie przekazuje selfjako formalny parametr do obiektów obiektów członkowskich wykonywanych w innym języku. To drobiazg i nie rozumiem, jak to naprawdę coś zmienia.

Ale nie mówię zbyt dobrze w Pythonie, więc na pewno brakuje mi rzeczy!


@delnan: Ach, tęskniłem „jawnie podaję siebie jako parametr formalny” .. Zgadnij, co dostaję za czytanie o 2
Demian Brecht

4
Wyraźne „ja” występuje również w Oberon, fwiw
grrussel,

Wyraźny parametr własny jest również używany we wspólnym systemie obiektów lisp. CLOS zapewnia jednak wiele metod, co oznacza, że ​​parametr własny nie jest w żaden sposób specjalny, tak jak w Pythonie.
Jules

1

Automatyczne przetwarzanie dokumentów, aby stały się własnością ich właściciela. Ogólnie rzecz biorąc, wszystkie genialne funkcje introspekcji Pythona sprawiają, że jest to bardzo unikalny język, od umiejętności korzystania z help () po możliwość używania go __doc__jako pierwszorzędnej właściwości obiektu. Na przykład:

>>> class DocStringException(Exception):
...     """Error message is the same as docstring"""
...     def __str__(self):
...         return repr(self.__doc__)
... 
>>> class ExampleException(DocStringException):
...     """An example happened"""
... 
>>> raise ExampleException
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.ExampleException: 'An example happened'

Inne przydatne funkcje introspekcji:

  • help / help () - pomoc z tłumaczem / pomoc z obiektem
  • słowa kluczowe - słowa kluczowe python
  • locals () - pobierz lokalne nazwy
  • globals () - pobierz nazwy globalne
  • dir () - pobiera właściwości i metody obiektu
  • metoda .mro. , issubclass - rozumienie dziedziczenia
  • id () - pobierz adres pamięci obiektu

Ruby ma prawie taką samą moc, jak Common Lisp, Clojure i wiele innych, dynamicznych języków, w które wierzę.
Torbjørn

@ Torbjørn która moc? Automatyczna dokumentacja czy funkcje introspekcji?
kojiro

Myślałem o obu. Nie dokładnie tak, ale w duchu. Nie wierzę, że Ruby ma takie same zdolności dokumentacyjne, ale na pewno introspekcja. CL i Clojure mają obie funkcje - i uważam, że introspekcja wykracza daleko poza to, co znajdziesz w Pythonie, ponieważ jest homoikoniczna .
Torbjørn

1
  1. Generator Expressions
  2. input()Pozwól, że wyjaśnię, jak dotąd nie widziałem języka, w którym można przypisać wartość do instrukcji, która coś wypisuje, przypomina ruby print/gets, ale z wartością przypisaną do wydruku zamiast:print "Foo" bar = gets
  3. yield
  4. Wiele rodzajów zestawów danych: ordereddict, namedtuple, array, list, tuple, dictionary

Wyrażenia generatora mogą być zaimplementowane w Haskell przy użyciu rozumienia list (listy Haskell są leniwe, w przeciwieństwie do list pythonowych, więc nie jest wymagana żadna konkretna składnia). Przez „wejście” zakładam, że masz na myśli funkcję python 3 o tej nazwie (ponieważ funkcja python 2 jest niebezpieczna i nie powinna być używana). To prawda, że ​​jest to niezwykła kombinacja zachowań (chociaż jest obecna w javascript - window.prompt - i BASIC, gdzie, jak sądzę, od tego, jak Python ją zapożyczył), ale może być trywialnie zaimplementowana przez programistę ("input s = putStrLn s >> getStrLn "zrobi to dla haskell).
Jules

Leniwy język, taki jak Haskell, tak naprawdę nie potrzebuje wydajności - może po prostu zwrócić listę zbudowaną przy użyciu zwykłych metod, a elementy będą generowane na żądanie. Mimo to biblioteka zawiera jawną implementację coroutines. Standardowa biblioteka Haskell zawiera wszystkie wspomniane struktury danych i wiele innych.
Jules

-2

Chodzi o to, że Python jest jednym z niewielu języków o wyjątkowo niskim nakładzie syntaktycznym, co daje mu ogromne możliwości ekspresji: rozumienie list / set / dict, wydajność, dekoratory, eval, programowanie w klasach, introspekcja, zoptymalizowane wbudowane struktury danych (listy, dyktanda, zestawy), wszystkie te rzeczy spisują się w bardzo miły sposób, aby dać tobie (deweloperowi) moc wyrażania swoich myśli zwięzłym i eleganckim kodem niemal tak szybko, jak tylko możesz myśleć. Tak naprawdę nie mogę wymyślić żadnego innego języka z tym zabójczym zestawem funkcji połączonych razem.


1
Jeśli uważasz, że Python ma niski narzut składniowy (pomimo nieprzyzwoicie skomplikowanej gramatyki i stosunkowo dużej ilości cukru składniowego), co myślisz o Schemacie?
Tikhon Jelvis

Eval naprawdę nie powinien być używany w żadnym programie produkcyjnym (chociaż przyznaję, że może się przydać do szybkich hacków). Jak pokazano w komentarzach do innych pytań, python nie jest w żaden sposób wyjątkowy pod względem tych funkcji. Uważam na przykład, że clojure ma wszystkie wymienione przez ciebie funkcje, a większość można zrobić za pomocą wspólnego seplenienia.
Jules

-4

Powiedziałbym, że to użycie wcięcia w celu dołączenia instrukcji i pętli. Nie widziałem tego w żadnym innym języku.

Myślę, że jest to bardzo przydatne, ponieważ znacznie utrudnia zaciemnienie kodu Pythona!

Wydaje się również, że działa w sposób uporządkowany wiersz po wierszu, z wyjątkiem funkcji, i może być również interpretowany jako taki, co jest miłe.


2
Wikipedia zna ekran pełen języków, które też to robią. Nazywa się to zasadą off-side .

3
Nie rozumiem. Wydaje się również, że działa ono w sposób uporządkowany wiersz po wierszu, z wyjątkiem funkcji, i może być interpretowane jako takie, co jest miłe. Co to znaczy?
kojiro
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.