Jakie są wady Pythona? [Zamknięte]

147

Python wydaje się teraz wściekły i nie bez powodu - ponieważ jest to naprawdę język, którym prawie się cieszy, gdy dostaje się nowy problem do rozwiązania. Ale, jak powiedział kiedyś mądry człowiek (nazywając go mędrcem tylko dlatego, że nie mam pojęcia, kto to powiedział; nie jestem pewien, czy on był w ogóle taki mądry), aby naprawdę znać język, którego nie tylko się zna składnia, design itp., zalety, ale także jego wady. Żaden język nie jest idealny, niektóre są po prostu lepsze niż inne.

Jakie byłyby Twoim zdaniem obiektywne wady Pythona.

Uwaga: nie pytam o porównanie języków (tj. C # jest lepszy niż Python, ponieważ ... yadda yadda yadda) - bardziej obiektywna (do pewnego stopnia) opinia, które funkcje językowe są źle zaprojektowane, czy to, co może niektórych brakuje w nim i tak dalej. Jeśli trzeba użyć innego języka jako porównania, ale tylko w celu zilustrowania kwestii, która w innym przypadku byłaby trudna do opracowania (tj. Dla ułatwienia zrozumienia)

Wieżowiec
źródło
50
Myślę, że jest to pomocne subiektywne pytanie i wstyd byłoby je zamknąć.
Eric Wilson
25
Wydaje się, że jest tutaj fanboy python, który po prostu zaniża wszystkie odpowiedzi anty-pythonowe.
zvrba
2
@TMN: Wciąż traktuje to białe znaki jako tokeny, po prostu ich nie zwraca - i właśnie to robi gramatyka Pythona.
9
@Roger: konwencja dotycząca SO polega na komentowaniu głosów negatywnych. Ponieważ jest to strona subiektywnych opinii, nie widzę powodu, by głosować negatywnie, szczególnie. bez komentarzy. Tak więc stoję przy moim „wzywaniu imienia”.
zvrba
8
@zvrba: Downvotes nadal oznacza „nieprzydatne”, jak zawsze.

Odpowiedzi:

109

Używam Pythona dość regularnie i ogólnie uważam, że jest to bardzo dobry język. Niemniej jednak żaden język nie jest idealny. Oto wady w kolejności według mnie osobiście:

  1. Jest wolny Mam na myśli naprawdę, bardzo powoli. Wiele razy to nie ma znaczenia, ale zdecydowanie oznacza, że ​​będziesz potrzebować innego języka dla bitów o kluczowym znaczeniu dla wydajności.

  2. Funkcje zagnieżdżone w pewnym sensie zasysają to, że nie można modyfikować zmiennych w zakresie zewnętrznym. Edycja: Nadal używam Pythona 2 ze względu na obsługę bibliotek, a ten błąd w projekcie denerwuje mnie, ale najwyraźniej został naprawiony w Pythonie 3 z powodu nielokalnej instrukcji. Nie mogę się doczekać, aż biblioteki, których używam, zostaną przeniesione, aby ten błąd mógł zostać przesłany na stos popiołów historii na dobre.

  3. Brakuje kilku funkcji, które mogą być przydatne do biblioteki / kodu generycznego, a IMHO upraszcza ekstremalne niezdrowe sytuacje. Najważniejsze, jakie mogę wymyślić, to typy wartości zdefiniowane przez użytkownika (domyślam się, że można je tworzyć za pomocą magii metaklasy, ale nigdy nie próbowałem) i parametr funkcji ref.

  4. To daleko od metalu. Potrzebujesz pisać operacje na wątkach, kod jądra czy coś takiego? Powodzenia.

  5. Chociaż nie przeszkadza mi brak możliwości wychwytywania błędów semantycznych z góry jako kompromis dla dynamizmu, który oferuje Python, chciałbym, aby istniał sposób na wychwycenie błędów składniowych i głupich rzeczy, takich jak błędne wpisywanie nazw zmiennych bez konieczności uruchamiania kodu.

  6. Dokumentacja nie jest tak dobra, jak języki takie jak PHP i Java, które mają silne zaplecze korporacyjne.

dsimcha
źródło
60
@Casey, muszę się nie zgodzić. Indeks jest okropny - spróbuj wyszukać withinstrukcję lub metody na list. Wszystko, co obejmuje samouczek, jest w zasadzie niemożliwe do przeszukania. Mam dużo więcej szczęścia z dokumentacją Microsoftu dla C ++.
Mark Ransom
17
Około 5 - wystarczy użyć płatków pyłu. Jest napisany, aby wychwycić dokładnie te błędy.
Alexander Solovyov
4
Jeśli chodzi o szybkość: wraz z pojawieniem się PyPy, wielu użytkowników Pythona będzie w stanie poradzić sobie z problemem prędkości tylko za pomocą interpretera z wbudowanym kompilatorem JIT (na razie użytkownicy Python 3 i użytkownicy modułów rozszerzających C nie obsługiwanych przez cpyext nie mam tej opcji).
ncoghlan
29
Nienawidzę dokumentów Pythona. Są z pewnością ładniejsze niż większość, ale wiele razy wiele przydatnych informacji jest gromadzonych na jednej stronie, takich jak metody na ciągach i listach - a wszystkie typy sekwencji są również grupowane. Kiedy przeszukuję te informacje, po prostu ląduję na ogromnym tomie i muszę przeszukać stronę, aby znaleźć to, czego chcę. Uważam też, że indeks na tych stronach jest trudny do odczytania, a czasem trudno jest powiedzieć, której sekcji chcę.
Carson Myers,
5
Jak odległość od metalu może być argumentem? Czy Python kiedykolwiek twierdził, że jest językiem systemowym?
Mark Canlas,
66

Nienawidzę tego, że Python nie potrafi rozróżnić deklaracji od użycia zmiennej. Aby to zrobić, nie potrzebujesz pisania statycznego. Byłoby po prostu miło powiedzieć „jest to zmienna, którą celowo deklaruję i zamierzam wprowadzić nową nazwę, to nie jest literówka”.

Ponadto zwykle używam zmiennych Python w stylu jednokrotnego zapisu, to znaczy traktuję zmienne jako niezmienne i nie modyfikuję ich po pierwszym przypisaniu. Dzięki takim funkcjom, jak przetwarzanie list, jest to niezwykle łatwe i ułatwia śledzenie przepływu kodu.

Nie mogę jednak udokumentować tego faktu. Nic w Pythonie nie uniemożliwia mi nadpisywania lub ponownego wykorzystywania zmiennych.

Podsumowując, chciałbym mieć dwa słowa kluczowe w języku: vari let. Jeśli piszę do zmiennej niezadeklarowanej przez żadną z nich, Python powinien zgłosić błąd. Ponadto letdeklaruje zmienne jako tylko do odczytu, podczas gdy varzmienne są „normalne”.

Rozważ ten przykład:

x = 42    # Error: Variable `x` undeclared

var x = 1 # OK: Declares `x` and assigns a value.
x = 42    # OK: `x` is declared and mutable.

var x = 2 # Error: Redeclaration of existing variable `x`

let y     # Error: Declaration of read-only variable `y` without value
let y = 5 # OK: Declares `y` as read-only and assigns a value.

y = 23    # Error: Variable `y` is read-only

Zauważ, że typy są nadal niejawne (ale letzmienne są statycznie typowane dla wszystkich celów i celów, ponieważ nie można ich przywrócić do nowej wartości, podczas gdy varzmienne mogą być nadal dynamicznie typowane).

Wreszcie wszystkie argumenty metody powinny być automatycznie let, tzn. Powinny być tylko do odczytu. Zasadniczo nie ma żadnego powodu, aby modyfikować parametr, z wyjątkiem następującego idiomu:

def foo(bar = None):
    if bar == None: bar = [1, 2, 3]

Można to zastąpić nieco innym idiomem:

def foo(bar = None):
    let mybar = bar or [1, 2, 3]
Konrad Rudolph
źródło
6
Tak bardzo chciałbym, aby Python miał zdanie „var”. Oprócz (bardzo dobrego) powodu, który podasz, znacznie ułatwiłby odczytanie kodu, ponieważ wtedy możesz po prostu zeskanować stronę, aby wykryć wszystkie deklaracje zmiennych.
jhocking
25
To tak, jakby programiści python zignorowali lekcje z przeszłości. Brak deklaracji zmiennych, brak deklaracji funkcji to błąd popełniony po raz pierwszy w latach 50. XX wieku. Te trudne do znalezienia błędy, które wynikały z trudnej do zauważenia literówki, były zadziwiająco pierwsze po raz pierwszy w latach 50. XX wieku. Ten błąd językowy był wielokrotnie (i później poprawiany). Deklarowanie zmiennych nie jest dużym obciążeniem. Wielokrotnie uratował mi tyłek. Nieuchronnie use strict;i use warnings;perl na skrypcie dowolnej wielkości. Python pozbawił programistę zbyt wielu pomocy do debugowania.
David Hammen,
19
@David, Aby być sprawiedliwym dla Pythona, podniesie wyjątek, jeśli spróbujesz uzyskać dostęp do zmiennej, która nie została przypisana. Wiele języków, w których nie ma deklaracji, zwróciłoby jakąś wartość domyślną. W rezultacie wersja Pythona jest znacznie mniej problematyczna niż te.
Winston Ewert
1
@yi_H Propozycja nie miała być kompatybilna wstecz - ani nawet prawdziwa. Pytanie brzmiało: „jakie są wady Pythona”… cóż, brak vari let(lub podobny mechanizm) jest wadą. Innymi słowy: gdybym był projektantem Pythona, zrobiłbym coś takiego. To powiedziawszy , przyszłe wersje mogą to obejmować, gdy załadujesz specjalny pakiet (podobny do __future__). Powiedzieć import strict. Tak się jednak nie stanie, ponieważ wymaga hacków składniowych…
Konrad Rudolph,
3
+1 Za dodanie lepszych „funkcjonalnych” umiejętności programowania.
Evan Plaice
44

Moja główna skarga dotyczy wątków, które w wielu okolicznościach nie są tak wydajne (w porównaniu z Javą, C i innymi) z powodu globalnej blokady interpretera (patrz „Wewnątrz Python GIL” (link PDF) )

Istnieje jednak interfejs wieloprocesowy, który jest bardzo łatwy w użyciu, jednak korzystanie z pamięci dla tej samej liczby procesów w porównaniu do wątków będzie większe, lub trudne, jeśli masz dużo wspólnych danych. Korzyścią jest jednak to, że gdy program działa z wieloma procesami, może być skalowany na wielu komputerach, czego nie może zrobić program wielowątkowy.

Naprawdę nie zgadzam się z krytyką dokumentacji, uważam, że jest ona doskonała i lepsza niż większość, jeśli nie wszystkie główne języki.

Ponadto możesz złapać wiele błędów środowiska uruchomieniowego, uruchamiając pylint .

Casey
źródło
2
+1 dla pylinta. Nie byłem tego świadomy. Następnym razem, gdy zrobię projekt w Pythonie, wypróbuję go. Również wielowątkowość wydaje się działać dobrze, jeśli użyjesz Jython zamiast referencyjnej implementacji CPython. OTOH Jython jest nieco wolniejszy niż CPython, więc może to częściowo pokonać cel.
dsimcha
3
Wątek nie jest dobrze obsługiwany? Biblioteki wątków istnieją już od 2.1.
rox0r,
2
Wiem, że istnieje obsługa wątków, ale w porównaniu z Javą lub C GIL naprawdę obniży Twoją wydajność. Dlatego moduł wieloprocesowy jest lepszy niż wątkowanie.
cmcginty,
2
Dokumentacja jest dobra, jeśli możesz ją znaleźć. Googling klas Java jest znacznie łatwiejszy niż Python.
Brendan Long,
@Casey Wyjaśniłem sformułowanie w odpowiedzi, ponieważ wątki są obsługiwane, po prostu wykazuje dziwną wydajność (dodano odniesienie i kilka linków do dokumentów)
dbr
28

Prawdopodobnie brak pisania statycznego, który może wprowadzić pewne klasy błędów w czasie wykonywania , nie jest wart dodatkowej elastyczności, jaką zapewnia pisanie kaczką.

Jakub
źródło
5
Jest to poprawne, chociaż istnieją narzędzia takie jak PyChecker, które mogą sprawdzać błędy, które mógłby zrobić kompilator w językach takich jak C / Java.
Oliver Weiler
24
Pisanie dynamiczne jest świadomą decyzją projektową, a nie wadą.
missingfaktor
14
To samo, co stwierdzenie, że słabością Javy jest brak dynamicznego pisania.
MAK
12
@missingfaktor, @MAK, oczywiście pisanie kaczek było zamierzoną funkcją. Ale większość decyzji projektowych wprowadza obiektywne korzyści i wady. Dodatkowa elastyczność kodu jest zaletą dynamicznego pisania, a dodatkowe klasy potencjalnych błędów w czasie wykonywania są wadą. Subiektywna część polega na tym, czy funkcja jest tego warta.
Jakub
6
Brak pisania statycznego ułatwia programistom pisanie kodu zawierającego błędy w czasie wykonywania. W języku C # int foo = 4; Console.Write(foo.Length);nie kompiluje się, więc błąd „Int32 nie ma właściwości Długość” nie może przypadkowo dostać się do opublikowanego oprogramowania. W Pythonie, chyba że uruchomisz opcjonalne narzędzia pomocnicze w celu wyszukania takich błędów, kod, który uzyskuje dostęp do nieistniejących elementów obiektów, może pozostać niewykryty, dopóki nie spowoduje to błędów w czasie wykonywania.
Jakub
27

Wydaje mi się, że zorientowane obiektowo części Pythona są jakby „przykręcone”. Cała potrzeba jawnego przekazania „siebie” każdej metodzie jest symptomem tego, że jej składnik OOP nie został wyraźnie zaplanowany , można powiedzieć; pokazuje także czasami brudzące zasady określania zakresu Pythona, które zostały skrytykowane w innej odpowiedzi.

Edytować:

Kiedy mówię, że zorientowane obiektowo części Pythona wydają się „przykręcone”, mam na myśli to, że czasami strona OOP wydaje się niespójna. Weźmy na przykład Ruby: w Ruby wszystko jest obiektem, a ty wywołujesz metodę przy użyciu znanej obj.methodskładni (oczywiście z wyjątkiem przeciążonych operatorów); w Pythonie wszystko też jest obiektem, ale niektóre metody wywołuje się jako funkcję; tzn. przeciążasz, __len__aby zwrócić długość, ale wywołujesz ją, używając len(obj)bardziej znanego (i spójnego) obj.lengthwspólnego w innych językach. Wiem, że istnieją powody tej decyzji projektowej, ale ich nie lubię.

Ponadto w modelu OOP Pythona brakuje jakiejkolwiek ochrony danych, tzn. Nie ma prywatnych, chronionych i publicznych członków; możesz je naśladować za pomocą metod _i __przed nimi, ale to trochę brzydkie. Podobnie, Python nie do końca rozumie aspekt OOP w zakresie przekazywania wiadomości.

mipadi
źródło
17
Parametr samo jest jedynie czyni wyraźne jakie inne języki pozostawić ukryte. Te języki mają wyraźnie „własny” parametr.
13
@Roger Pate: Tak, ale ta wyraźna potrzeba „jaźni” jest w pewnym sensie denerwująca (i, powiedziałbym, nieszczelna abstrakcja). Nie była to również celowa decyzja projektowa, ale z powodu „dziwnych” reguł określania zakresu Pythona. Nie mogę szybko znaleźć tego artykułu, ale jest wiadomość e-mail od Guido van Rossuma, która dobrze wyjaśnia, dlaczego wymagany jest parametr „self”.
mipadi
2
@Roger Pate: W językach obiektowych przekazanie celu jako pierwszego parametru nadal można uznać za szczegół implementacji. Nie chodzi mi jednak o to, czy to dobry pomysł, czy nie; chodzi o to, że w Pythonie nie jest to spowodowane świadomą decyzją projektową, ale raczej obejściem brodawek w systemie określania zakresu.
mipadi
3
@mipadi: Aktualizacja ma lepsze rozumowanie (więc usunę downvote), ale jeśli postrzegasz len jako operatora, którego przeciążasz, w Pythonie jest więcej OO. Chciałbym zobaczyć przykład lub uzasadnienie, w jaki sposób Python źle przekazuje wiadomość.
8
Jawne ja jest wynikiem tego, że metody są tylko funkcjami (i, jak zauważył Winston, niejawnymi deklaracjami zmiennych lokalnych). Nie możesz spodobać się tej decyzji projektowej, ale głupio jest nazywać OOP „boleśnie” w języku, w którym wszystko jest dostępne jako obiekt w czasie wykonywania.
ncoghlan
19

Czego nie lubię w Pythonie:

  1. Wątki (wiem, że już o tym wspominano, ale warto o nich wspomnieć w każdym poście).
  2. Brak obsługi wieloliniowych funkcji anonimowych ( lambdamoże zawierać tylko jedno wyrażenie).
  3. Brak prostego, ale potężnego Funkcja wejścia czytania / klasa (jak cinczy scanfw C ++ i C lub ScannerJava).
  4. Domyślnie wszystkie ciągi znaków nie są Unicode (ale są poprawione w Pythonie 3).
MAK
źródło
5
Jeśli chodzi o (2), myślę, że jest to równoważone możliwością zagnieżdżenia funkcji.
Konrad Rudolph,
3
@KonradRudolph Moją główną cechą z zagnieżdżonymi funkcjami zamiast wieloliniowych lambd jest zamiana kolejności odczytu.
CookieOfFortune
2
@wkschwartz: raw_inputi 'sys.stdin' są dość gołe. Nie obsługują pobierania sformatowanych danych wejściowych (np. „% D:% d:% d”% (godzina, minuta, sekunda) do odczytu w czasie). Jak dotąd Python nie ma nic wspólnego z funkcjonalnością scanf (w C) lub Scanner (Java).
MAK
2
@limscoder: Wszystkie ciągi znaków są domyślnie Unicode w Javie. Nie widzę dobrego powodu, aby mieć osobne klasy str i Unicode. IMHO, ciągi i tablice bajtów nie powinny być reprezentowane przez tę samą abstrakcję. Klasa ciągów powinna być przeznaczona do przechowywania i manipulowania tekstem - którego wewnętrznej reprezentacji tak naprawdę nas nie obchodzi. Nie powinniśmy chcieć robić takich rzeczy, jak obcinanie / zastępowanie / usuwanie / wstawianie w określonym bajcie w ciągu - chcemy to robić w określonym znaku . Łatwo zapomnieć o tym rozróżnieniu i wysadzić swój kod, gdy wprowadzane są dane w języku innym niż angielski.
MAK
1
@limscoder: jeśli chcesz zobaczyć łatwy Unicode, spróbuj Tcl. Kilka lat temu musiałem przełączyć się z Tcl na Python, a chłopiec był zaskoczony, jak porównuje się obsługa prymitywnego kodu Pythona. Jest to naprawdę niewidoczne w Tcl i powoduje duży problem w pythonie.
Bryan Oakley,
18

Domyślne argumenty ze zmiennymi typami danych.

def foo(a, L = []):
    L.append(a)
    print L

>>> foo(1)
[1]
>>> foo(2)
[1, 2]

Zwykle jest to wynikiem pewnych subtelnych błędów. Myślę, że byłoby lepiej, gdyby tworzył nowy obiekt listy za każdym razem, gdy wymagany był domyślny argument (zamiast tworzyć pojedynczy obiekt do użycia dla każdego wywołania funkcji).

Edycja: To nie jest duży problem, ale kiedy coś trzeba odwołać w dokumentacji, zwykle oznacza to, że jest to problem. Nie powinno to być wymagane.

def foo(a, L = None):
    if L is None:
        L = []
    ...

Zwłaszcza gdy powinno to być ustawienie domyślne. To po prostu dziwne zachowanie, które nie odpowiada oczekiwaniom i nie jest przydatne w wielu okolicznościach.

jsternberg
źródło
Widzę wiele skarg na ten temat, ale dlaczego ludzie domagają się posiadania pustej listy (modyfikowanej przez funkcję) jako domyślnego argumentu? Czy to naprawdę taki duży problem? Czy to prawdziwy problem?
Martin Vilcans
8
Narusza to zasadę najmniejszego zaskoczenia. Nie można oczekiwać, że parametry funkcji przetrwają podczas wywołań.
aib
Jest to konsekwencja tego, że jest językiem skryptowym. Ten błąd Cię zaskoczy tylko RAZ, i nigdy więcej. Zrozumienie tego błędu naprawdę daje ci kopniaka w tyłek, aby przypomnieć, że tak, to wciąż jest język skryptowy. A to tylko dlatego, że język dobrze ukrywa aspekt skryptowy (zakładając, że używasz go poprawnie).
Zoran Pavlovic
@ZoranPavlovic z ciekawości, dlaczego jest to konsekwencja faktu, że jest to język skryptowy? Wydaje się, że jest to problem z tym, kiedy dane są powiązane i ponieważ listy są zmienne (które są dwie rzeczy, które zwykle są dobre, ale kończą się źle, gdy są połączone). Ten sam problem może wystąpić w języku innym niż skryptowy, jeśli dane zostaną powiązane w momencie tworzenia funkcji zamiast tworzenia nowej listy za każdym razem, gdy funkcja zostanie wywołana.
jsternberg
@aib: Nie sądzę - parametr tutaj, jak każdy inny obiekt Pythona - jest wskaźnikiem do obiektu. W tym przypadku obiekt jest zmienny, a zmienna jest powiązana, gdy funkcja jest zadeklarowana. Ten parametr „przetrwa połączenia”, ale przetrwa odniesienie do obiektu zmiennego.
Patrick Collins,
14

Niektóre funkcje Pythona, które czynią go tak elastycznym jak język programowania, są również postrzegane jako główne wady tych, które są wykorzystywane do analizy statycznej „całego programu” przeprowadzanej przez proces kompilacji i łączenia w językach takich jak C ++ i Java.

  • Domniemana deklaracja zmiennych lokalnych

Zmienne lokalne są deklarowane za pomocą zwykłej instrukcji przypisania. Oznacza to, że powiązania zmiennych w dowolnym innym zakresie wymagają od kompilatora jawnej adnotacji (globalne i nielokalne deklaracje dla zakresów zewnętrznych, notacja dostępu do atrybutów na przykład dla zakresów). To znacznie zmniejsza ilość płyty kotłowej potrzebnej przy programowaniu, ale oznacza, że ​​do przeprowadzania kontroli obsługiwanych przez kompilator w językach wymagających wyraźnych deklaracji zmiennych potrzebne są narzędzia do analizy statycznej innych firm (takie jak płatki py).

  • Obsługiwane jest „łatanie małp”

Zawartość modułów, obiektów klasy, a nawet wbudowanej przestrzeni nazw można modyfikować w czasie wykonywania. Jest to niezwykle potężny, umożliwiający wiele niezwykle przydatnych technik. Jednak ta elastyczność oznacza, że ​​Python nie oferuje niektórych funkcji wspólnych dla statycznych języków OO. W szczególności parametr „self” dla metod instancji jest raczej jawny niż niejawny (ponieważ „metod” nie trzeba definiować wewnątrz klasy, można je później dodać poprzez modyfikację klasy, co oznacza, że ​​nie jest to szczególnie praktyczne niejawnie przekazać odwołanie do instancji) i kontroli dostępu do atrybutu nie można łatwo egzekwować w zależności od tego, czy kod znajduje się „wewnątrz”, czy „poza” klasą (ponieważ to rozróżnienie istnieje tylko podczas wykonywania definicji klasy).

  • Daleko od metalu

Dotyczy to również wielu innych języków wysokiego poziomu, ale Python ma tendencję do wyabstrahowywania większości szczegółów sprzętowych. Języki programowania systemów, takie jak C i C ++, są nadal znacznie lepiej przystosowane do obsługi bezpośredniego dostępu do sprzętu (jednak Python z przyjemnością porozmawia z tymi za pomocą modułów rozszerzeń CPython lub, bardziej przenośnie, za pośrednictwem ctypesbiblioteki).

ncoghlan
źródło
12
  1. Korzystanie z wcięcia bloków kodu zamiast {} / begin-end, cokolwiek.
  2. Każdy nowszy współczesny język ma odpowiednie zakresy leksykalne, ale nie Python (patrz poniżej).
  3. Chaotyczne dokumenty (porównaj z dokumentacją Perl5, która jest znakomita).
  4. Kaftan bezpieczeństwa (jest tylko jeden sposób, aby to zrobić).

Przykład zepsutego określania zakresu; transkrypcja z sesji tłumacza:

>>> x=0
>>> def f():
...     x+=3
...     print x
... 
>>> f()
Traceback (most recent call last):
  File "", line 1, in ?
  File "", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

globali nonlocalwprowadzono słowa kluczowe, aby załatać tę głupotę projektu.

zvrba
źródło
2
jeśli chodzi o zakres, warto zainteresować się python.org/dev/peps/pep-3104, aby zrozumieć uzasadnienie obecnej metody.
Winston Ewert
Zgadzam się z +1. Więc +1.
Jas
34
Zaletą jest posiadanie jednego sposobu. Kiedy czytasz czyjś kod, nie odszyfrujesz ani jednej instrukcji. Gdy tylko idiomy zostaną zapisane w twoim mózgu, powinieneś mieć natychmiastowe rozpoznanie.
rox0r,
9
Całkowicie zgadzam się z @ rox0r. „Prosta kurtka” zapobiega wszelkim rodzajom wojen składniowych.
keithjgrant
8
Szczerze mówiąc, bardzo rzadko potrzebuję słów kluczowych globallub nonlocalw Pythonie. Tak rzadko, że zapominam, że ten problem istnieje i muszę go ponownie wyszukać w Google, gdy pojawia się kilka razy, mimo że piszę kod Python codziennie w pracy. Dla mnie kod, który musi modyfikować zmienne globalne (lub, co gorsza, zewnętrzne zmienne nieglobalne) jest zapachem kodu. Zwykle jest (nie zawsze) lepszy sposób.
Ben
11

Uważam, że kombinacja składni obiektowej this.method()i method(this)składni proceduralnej / funkcjonalnej Pythona jest bardzo niepokojąca:

x = [0, 1, 2, 3, 4]
x.count(1)
len(x)
any(x)
x.reverse()
reversed(x)
x.sort()
sorted(x)

Jest to szczególnie złe, ponieważ duża liczba funkcji (a nie metod) jest po prostu zrzucana do globalnej przestrzeni nazw : metody odnoszące się do list, ciągów, liczb, konstruktorów, metaprogramowania, wszystkie zmieszane w jedną dużą listę posortowaną alfabetycznie.

Przynajmniej w językach funkcjonalnych, takich jak F #, wszystkie funkcje mają odpowiednio rozmieszczone nazwy w modułach:

List.map(x)
List.reversed(x)
List.any(x)

Więc nie wszyscy są razem. Co więcej, jest to standard przestrzegany w całej bibliotece, więc przynajmniej jest spójny.

Rozumiem powody, dla których warto wykonać funkcję vs metoda , ale nadal uważam, że złym pomysłem jest mieszanie ich w ten sposób. Byłbym znacznie szczęśliwszy, gdyby przestrzegano składni metody, przynajmniej w przypadku typowych operacji:

x.count(1)
x.len()
x.any()
x.reverse()
x.reversed()
x.sort()
x.sorted()

Niezależnie od tego, czy metody mutują, czy nie, posiadanie ich jako metod na obiekcie ma kilka zalet:

  • Jedno miejsce do wyszukiwania „typowych” operacji na typie danych: inne biblioteki / etc. mogą mieć inne wymyślne rzeczy, które mogą zrobić z typami danych, ale wszystkie operacje „domyślne” są w metodach obiektu.
  • Nie musisz powtarzać, Modulekiedy dzwonisz Module.method(x). Biorąc powyższy przykładowy wykaz funkcji, dlaczego muszę ciągle powtarzać List? Powinien wiedzieć, że jest to Listi nie chcę wywoływać tej Navigation.map()funkcji! Korzystanie ze x.map()składni powoduje, że jest ona SUCHA i nadal jednoznaczna.

I oczywiście ma to zalety w porównaniu z metodą umieszczania wszystkiego w globalnej przestrzeni nazw . To nie jest tak, że obecny sposób nie jest w stanie zrobić rzeczy. Jest to nawet dość terse ( len(lst)), ponieważ nic nie ma przestrzeni nazw! Rozumiem zalety korzystania z funkcji (zachowanie domyślne itp.) W stosunku do metod, ale nadal mi się to nie podoba.

To jest po prostu bałagan. A w dużych projektach bałagan jest twoim największym wrogiem.

Haoyi
źródło
1
tak ... Naprawdę tęsknię za stylem LINQ (jestem pewien, że LINQ nie jest pierwszym, który go wdrożył, ale najbardziej go znam) z obsługą listy.
CookieOfFortune
1
Nie myśl o len (x) jako metodzie. „len” jest funkcją. Python ma funkcje i metody i nie widzę nic złego w tym podejściu. Brak odpowiednich funkcji jest zwykle źródłem niepotrzebnego pisania.
rbanffy
Wiem, że len()jest funkcją i jakie są zalety. Stwierdziłem także, dlaczego uważam, że to zły pomysł, dlaczego uważam, że funkcje globalne są szczególnie złym pomysłem i dlaczego uważam, że metody zapewniają wygodną metodę organizowania i określania zakresu twojej funkcjonalności =)
Haoyi
Nie sądzę, że 42 (a może 43?) Słowa kluczowe to „duża” liczba. Która obejmuje również takie rzeczy def, classi inne połączenia non-funkcyjne. Porównaj to z ponad 100 w większości innych popularnych języków. Należy także rozważyć linię z import this: Namespaces are one honking great idea -- let's do more of those!. Myślę, że możesz źle zrozumieć przestrzenie nazw Python;)
Wayne Werner,
8

Brak homoikoniczności .

Python musiał poczekać, aż 3.x doda słowo kluczowe „z”. W każdym języku homoikonicznym można go trywialnie dodać do biblioteki.

Większość innych problemów, które widziałem w odpowiedziach, należą do jednego z 3 rodzajów:

1) Rzeczy, które można naprawić za pomocą oprzyrządowania (np. Płatki pyłu) 2) Szczegóły implementacji (GIL, wydajność) 3) Rzeczy, które można naprawić za pomocą standardów kodowania (tj. Cechy, których ludzie nie chcieliby, aby ich nie było)

# 2 nie jest problemem z językiem, IMO # 1 i # 3 nie są poważnymi problemami.

Aidenn
źródło
1
withbył dostępny z Pythona 2.5 from __future__ import with_statement, ale zgadzam się, czasami okazało się, że niefortunne jest to, że instrukcje takie jak if/ for/ print/ etc są „specjalne” zamiast zwykłych funkcji
dbr
7

Python jest moim ulubionym językiem, ponieważ jest bardzo ekspresyjny, ale wciąż powstrzymuje cię od popełniania zbyt wielu błędów. Nadal mam kilka rzeczy, które mnie denerwują:

  • Brak prawdziwych anonimowych funkcji. Lambda może być używana do funkcji pojedynczej instrukcji, a withinstrukcja może być używana do wielu rzeczy, w których użyjesz bloku kodu w Rubim. Ale w niektórych sytuacjach sprawia, że ​​rzeczy są nieco bardziej niezgrabne, niż musiałyby być. (Daleko od tak niezdarnego, jak by to było w Javie, ale nadal ...)

  • Pewne zamieszanie w relacji między modułami i plikami. Uruchamianie „python foo.py” z wiersza poleceń różni się od „import foo”. Względny import w Pythonie 2.x może również powodować problemy. Mimo to moduły Pythona są o wiele lepsze niż odpowiednie funkcje C, C ++ i Ruby.

  • Jawne self. Mimo że rozumiem niektóre z tego przyczyn i chociaż codziennie używam Pythona, często popełniam błąd, zapominając o tym. Innym problemem jest to, że tworzenie klasy z modułu staje się nieco nudne. Jawne ja wiąże się z ograniczonym zasięgiem, na który narzekali inni. Najmniejszy zakres w Pythonie to zakres funkcji. Jeśli utrzymujesz swoje funkcje na małym poziomie, tak jak powinieneś, nie jest to problem sam w sobie, a IMO często daje czystszy kod.

  • Niektóre funkcje globalne, takie jak len, że można oczekiwać, że będzie to metoda (która faktycznie jest za kulisami).

  • Znaczące wcięcie. Nie sam pomysł, który moim zdaniem jest świetny, ale ponieważ jest to jedyna rzecz, która powstrzymuje tylu ludzi przed wypróbowaniem Pythona, być może lepiej byłoby dla Pythona z niektórymi (opcjonalnymi) symbolami początku / końca. Ignorując tych ludzi, mógłbym całkowicie żyć z wymuszonym rozmiarem wcięcia.

  • Że nie jest to wbudowany język przeglądarek internetowych, a nie JavaScript.

Spośród tych skarg to tylko pierwsza, na tyle mi zależy, że myślę, że należy ją dodać do języka. Inne są raczej niewielkie, z wyjątkiem ostatniego, co byłoby wspaniałe, gdyby tak się stało!

Martin Vilcans
źródło
+1 Zastanawiam się, czy napisać, datetime.datetime.now()kiedy jeden projekt mógłby napisać, datetime.nowa następnie pomieszanie dwóch projektów w jeden sposób wyklucza drugi i na pewno nie zdarzyłoby się to w Javie, która nie nazwałaby modułu tak samo jak plik (?) Jeśli widzisz, jak często zdarza się, że moduł myli nas z plikiem, gdy oba zastosowania są praktykowane i jawne self, wciąż próbuję zrozumieć, ponieważ wywołania nie mają takiej samej liczby argumentów jak funkcje. I możesz pomyśleć, że python VM jest wolny?
Niklas Rosencrantz
Jeśli chodzi o twój problem z jawnym słowem kluczowym self. Czy mogę zasugerować użycie dobrego IDE dla Pythona? Wiem, że PyDev na platformie Eclipse automatycznie uzupełnia samodzielną część podpisu funkcji, jeśli wykryje, że piszesz wewnątrz klasy.
Zoran Pavlovic
5

Python nie jest w pełni dojrzały: język Python 3.2 ma w tej chwili problemy ze zgodnością z większością obecnie dystrybuowanych pakietów (zazwyczaj są one kompatybilne z Pythonem 2.5). Jest to duża wada, która obecnie wymaga większego wysiłku programistycznego (znajdź potrzebny pakiet, sprawdź kompatybilność; zważ, wybierając niezbyt dobry pakiet, który może być bardziej kompatybilny; weź najlepszą wersję, zaktualizuj ją do wersji 3.2, co może zająć kilka dni; następnie zacznij robić coś pożytecznego).

Prawdopodobnie w połowie 2012 roku będzie to mniej mankamentem.

Zauważ, że chyba zostałem oceniony przez jednego z fanów-fanów. Podczas dyskusji programistów nasz zespół programistów wysokiego szczebla doszedł jednak do tego samego wniosku.

Dojrzałość w jednym głównym znaczeniu oznacza, że ​​zespół może korzystać z tej technologii i bardzo szybko działać bez ukrytych zagrożeń (w tym problemów ze zgodnością). Pakiety Python innych firm i wiele aplikacji nie działa w wersji 3.2 dla większości dzisiejszych pakietów. Powoduje to więcej pracy związanej z integracją, testowaniem, ponownym wdrażaniem samej technologii zamiast rozwiązywania danego problemu == mniej dojrzałej technologii.

Aktualizacja z czerwca 2013 r .: Python 3 nadal ma problemy z dojrzałością. Co jakiś czas członek zespołu wspomina o potrzebnym pakiecie, a następnie mówi „z wyjątkiem tylko wersji 2.6” (w niektórych przypadkach wdrożyłem obejście za pośrednictwem gniazda localhost, aby używać pakietu tylko w wersji 2.6 z wersją 2.6 i resztą nasze narzędzia pozostają w wersji 3.2). Nawet MoinMoin, wiki o czystym pythonie, nie jest napisane w Pythonie 3.

Jonathan Cline IEEE
źródło
2
Zgadzam się z tobą tylko wtedy, gdy twoja definicja dojrzałości jest niezgodna z wersją niezgodną z założenia .
tshepang 17.07.11
3
Zgadzam się, że dwa niekompatybilne strumienie Pythona stanowią problem (choć zrozumiałe, dlaczego tak się stało), ale nie uważam tego za kwestię „dojrzałości”.
Winston Ewert
Dojrzałość w jednym sensie oznacza, że ​​zespół może korzystać z tej technologii i bardzo szybko działać bez ukrytych zagrożeń (w tym problemów ze zgodnością). Pakiety Python innych firm i wiele aplikacji nie działa w wersji 3.2 dla większości dzisiejszych pakietów. Powoduje to więcej pracy związanej z integracją, testowaniem, ponownym wdrażaniem samej technologii zamiast rozwiązywania danego problemu == mniej dojrzałej technologii.
Jonathan Cline IEEE,
2
Następnie wystarczy użyć Python 2.x. Wiesz ... wersja, z której wszyscy korzystają. Lub przeczytaj dokumentację pakietów przez 2 sekundy, aby dowiedzieć się, z którymi wersjami jest kompatybilna.
jsternberg
2
„To, że Python 3.0 został wydany od jakiegoś czasu, nie oznacza, że ​​należy go używać. Python 3.0 i 2.x są rozwijane w tym samym czasie. Mam nadzieję, że w przyszłości wszyscy będziemy mogli używać python 3.0, ale na razie używanie 2.x to dobre rozwiązanie ”-> To 500-znakowy sposób powiedzenia: nie jest jeszcze dojrzały.
Jonathan Cline IEEE
4

Zakres Pythona jest poważnie uszkodzony, co sprawia, że ​​programowanie obiektowe w Pythonie jest bardzo niewygodne.

Mason Wheeler
źródło
8
czy możesz podać przykład? (Jestem pewien, że masz rację, ale chciałbym przykład)
Winston Ewert
24
Lubię Pythona, ale absolutnie nie znoszę umieszczać self.przed każdym odwołaniem do właściwości i metody wystąpienia. Uniemożliwia użycie Pythona do tworzenia DSL, tak jak to jest tak łatwe w Ruby.
Adam Crossland
35
Nie czuję się niezręcznie, lubię tę jawność.
Winston Ewert
9
Nie rozumiem, o co w tym wszystkim chodzi. W C ++, Javie i D ludzie często czynią zmienne składowymi jawnymi przez konwencję, na przykład przez poprzedzenie ich znakiem podkreślenia.
dsimcha
7
Używasz self w metodach innych niż deklaracja: def foo (self) ale self.foo (). Uważam, że ta mieszanka wyraźnej definicji, ale ukrytych rzeczy za kulisami, nie jest zbyt ładna.
LennyProgrammers
4

Moje obawy dotyczące Pythona:

  • Przykręcone OOP (patrz @ mipadi w celu uzyskania szczegółowych informacji na ten temat)
  • Zepsuta implementacja lambd
  • Problemy z zakresem
  • Brak trwałych kolekcji w standardowej bibliotece
  • Słaba podatność na osadzone DSL
missingfaktor
źródło
Dlaczego głosowanie negatywne?
missingfaktor
Nie jestem downvoter, ale czy możesz wyjaśnić, dlaczego uważasz, że OO jest zaryglowany? Python zawsze miał OO, jest to podstawowa część języka.
Daenyth,
Zobacz odpowiedź @ mipadi.
missingfaktor
4

Modyfikatory dostępu w Pythonie nie są egzekwowalne - utrudnia pisanie dobrze ustrukturyzowanego, zmodularyzowanego kodu.

Przypuszczam, że jest to część zepsutego ustalania zasięgu @ Masona - ogólnie duży problem z tym językiem. W przypadku kodu, który powinien być czytelny, wydaje się dość trudne do określenia, co może i powinno być w zakresie i jaką wartość będzie w danym momencie - obecnie myślę o przejściu z języka Python z powodu tych wad .

To, że „wszyscy zgadzamy się na dorosłych” nie oznacza, że ​​nie popełniamy błędów i nie pracujemy lepiej w ramach silnej struktury, szczególnie podczas pracy nad złożonymi projektami - wcięcia i bezsensowne podkreślenia nie wydają się wystarczające .

Mikey
źródło
Więc brak kontroli dostępu jest zły ... ale jawne określenie zakresu zapisów zmiennych w dowolnej nielokalnej przestrzeni nazw jest również złe?
ncoghlan
@ ncoghlan: 1 - ta funkcja jest standardem w wielu nowoczesnych językach, w zależności od konfiguracji projektu. 2 - Jest pod kontrolą programisty. 3 - nie jestem pewien, co jest w tym takiego wspaniałego - możesz łatwo kontrolować swój zakres za pomocą kilku ustawień projektu w większości skompilowanych języków / IDE. Jeśli „wszyscy zgadzamy się na dorosłych”, powinniśmy móc podejmować własne decyzje i dostosowywać zakres zgodnie z naszym poziomem komfortu.
Wektor
2
Chodzi o to, że ludzie proszący o „wymuszoną kontrolę dostępu” proszą nas o wyciągnięcie jednej z tych rzeczy, które sprawiają, że Python jest tak świetnym językiem kleju: celowo trudno jest programistom kontrolować, w jaki sposób ich kod będzie później używany. Ile elementów wzorcowych we wzorcach C ++ i Java istnieje wyłącznie w celu obejścia wymuszonych kontroli dostępu? Z pewnością rozumiem ludzi, którzy z tych powodów nie chcą używać Pythona, ale statyczne wymuszanie nigdy nie zastąpi rygorystycznych testów.
ncoghlan
1
@ ncoghlan - dla mnie najważniejsze w Pythonie są elegancja składni i prostota - ekspresyjność. I jak powiedziałem, zakresowanie ma mniej wspólnego z programistami, którzy mają problemy z tym, czego nie powinni, niż ze strukturą i organizacją kodu - więc koncepcja „zgody dorosłych” jest dyskusyjna. Pracuję nad złożonymi projektami, a nie prostymi narzędziami i skryptami - kod musi być starannie zmodularyzowany i ustrukturyzowany - modyfikatory dostępu są jednym z najważniejszych sposobów zapewnienia tego.
Wektor
1
A przegląd kodu, szkolenie i analiza sprzężenia to inne. Dla mnie wymuszone kontrole dostępu mieszczą się w tym samym segmencie, co pisanie statyczne: pomagają zapewnić dodatkowe zaufanie do poprawności (ale niewystarczające, aby uniknąć konieczności obszernego testowania), ale przy wysokich kosztach wydajności programistycznej. (Na poziomie praktycznym kontrola dostępu do atrybutów klas również nie pasuje do modelu obiektowego Pythona, w którym metody są zwykłymi funkcjami pobranymi z klas. Granica „wewnątrz / na zewnątrz” dla klas tak naprawdę nie istnieje, więc nie może być wymuszone)
ncoghlan
3
  1. Wydajność nie jest dobra, ale poprawia się z pypy,
  2. GIL zapobiega użyciu wątków w celu przyspieszenia kodu (chociaż jest to zwykle przedwczesna optymalizacja),
  3. Przydaje się tylko do programowania aplikacji,

Ale ma kilka wspaniałych funkcji odkupienia:

  1. Jest idealny dla RAD,
  2. Łatwo jest połączyć się z C (i aby C mógł osadzić interpreter Pythona),
  3. Jest bardzo czytelny,
  4. Łatwo się nauczyć,
  5. Jest dobrze udokumentowany,
  6. Baterie są naprawdę włączone, standardowa biblioteka jest ogromna, a pypi zawiera moduły do ​​praktycznie wszystkiego,
  7. Ma zdrową społeczność.
dan_waterworth
źródło
Co zainspirowało do wspomnienia o zaletach? Pytanie o problemy. Tak czy inaczej, co masz na myśli tylko przy programowaniu aplikacji? Jakie jest inne programowanie? Co konkretnie nie jest dobre?
tshepang
5
Wymieniłem zalety, ponieważ uważam, że przewyższają wady. Czy kiedykolwiek próbowałeś zaimplementować moduł jądra Linux w Pythonie.
dan_waterworth
3

Jestem zwolennikiem Pythona, a pierwszą wadą, która przychodzi mi na myśl, jest to, że komentując takie zdanie if myTest():, musisz zmienić wcięcie całego wykonanego bloku, którego nie musiałbyś robić w C lub Javie. W rzeczywistości w pythonie zamiast komentowania klauzuli if zamiast tego zacząłem komentować w ten sposób: `if True: #myTest (), więc nie będę musiał zmieniać następującego bloku kodu. Ponieważ Java i C nie polegają na wcięciach, komentowanie instrukcji jest łatwiejsze w C i Javie.

Niklas Rosencrantz
źródło
1
Poważnie zmodyfikowałbyś kod C lub Java, aby zmienić poziom bloku jakiegoś kodu bez zmiany jego wcięcia?
Ben
4
@Ben Tymczasowo tak ...
alternatywnie
1
@ben to samo tutaj.
Christopher Mahan
2
Używam sztuczki zmiany if something()na if False and something(). Inną sztuczką jest „komentowanie” przy użyciu ciągu wieloliniowego.
Martin Vilcans
1
@ Martin Oczywiście! jeśli False ...
Christopher Mahan
3

Wysyłka wielokrotna nie integruje się dobrze z ustalonym systemem pojedynczej wysyłki i nie jest bardzo wydajna.

Ładowanie dynamiczne jest ogromnym problemem w równoległych systemach plików, w których semantyka podobna do POSIX prowadzi do katastrofalnych spowolnień w operacjach intensywnie wykorzystujących metadane. Mam kolegów, którzy spalili ćwierć miliona godzin pracy po prostu ładując Pythona (z numpy, mpi4py, petsc4py i innymi modułami rozszerzeń) na rdzeniach 65k. (Symulacja przyniosła znaczące nowe wyniki naukowe, więc było warto, ale jest to problem, gdy pali się więcej niż baryłkę ropy, aby załadować Pythona raz.) Brak możliwości statycznego połączenia zmusił nas do podjęcia wielkich skręceń, aby uzyskać rozsądne czasy ładowania w skali, w tym łatanie libc-rtld, aby umożliwić dostęp do dlopenzbiorowego systemu plików.

Jed
źródło
Wow, wydaje się wysoce techniczny, czy masz jakieś materiały referencyjne, przykłady, posty na blogu lub artykuły na ten temat? Zastanawiam się, czy mogę być narażony na takie przypadki w najbliższej przyszłości.
vincent
Aron wygłosił wykład na SciPy 2012 . dlopenRzeczy jest w naszym collfs bibliotece. To repozytorium zawiera także dodatkowe sztuczki zipimport inspirowane buforowaniem ścieżki przez Ashera Langtona. Pracujemy nad lepszą dystrybucją i dokumentem.
Jed
3
  • spora część bardzo popularnych bibliotek i oprogramowania innych firm, które są szeroko stosowane, nie są pytoniczne. Kilka przykładów: soaplib, openerp, reportlab. Krytyka jest poza zakresem, jest tam, jest powszechnie używana, ale powoduje zamieszanie w kulturze Pythona (szkodzi motto, które mówi: „Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób”). Wydaje się, że znane sukcesy w Pythonie (takie jak django lub trac) są wyjątkiem.
  • potencjalnie nieograniczona głębokość abstrakcji instancji, klasy i metaklasy jest koncepcyjnie piękna i wyjątkowa. Ale aby go opanować, musisz dokładnie znać interpretera (w jakiej kolejności interpretowany jest kod python itp.). Nie jest powszechnie znany i używany (lub używany poprawnie), podczas gdy podobna czarna magia, taka jak generyczne C #, która jest koncepcyjnie bardziej skomplikowana (IMHO), wydaje się bardziej znana i stosowana proporcjonalnie.
  • aby dobrze zrozumieć model pamięci i wątków, musisz mieć duże doświadczenie z Pythonem, ponieważ nie ma obszernej specyfikacji. Po prostu wiesz, co działa, może dlatego, że czytasz źródła tłumacza lub doświadczasz dziwactw i odkryłeś, jak je naprawić. Na przykład istnieją tylko mocne lub słabe referencje, a nie miękkie i fantomowe referencje java. Java ma wątek do wyrzucania elementów bezużytecznych, podczas gdy nie ma formalnej odpowiedzi na temat tego, kiedy odbywa się to w Pythonie; możesz po prostu zauważyć, że wyrzucanie elementów bezużytecznych nie ma miejsca, jeśli nie jest wykonywany kod Pythona, i wyciągnij wniosek, że prawdopodobnie dzieje się to czasami podczas próby przydzielenia pamięci. Może to być trudne, gdy nie wiesz, dlaczego zablokowany zasób nie został zwolniony (moje doświadczenie na ten temat to mod_python we freeswitchu).

W każdym razie python jest moim głównym językiem od 4 lat. Bycie fanboyem, elitą lub monomanią nie jest częścią kultury pytona.

Vincent
źródło
+1. Specyfikacja pamięci i modelu wątków jest poprawna. Ale FWIW, moduł zbierający śmieci Java w wątku (i większość wszystkiego w GC) nie jest aspektem języka Java lub specyfikacji VM per se, ale jest kwestią konkretnej implementacji JVM. Jednak główna maszyna Sun / Oracle JVM jest szczegółowo udokumentowana w zachowaniu GC i możliwościach konfiguracji, o ile publikowane są całe książki o tuningu JVM. Teoretycznie CPython można udokumentować w ten sam sposób, niezależnie od specyfikacji języka.
Andrew Janke
2
  • Dziwne OOP:
    • len(s)poprzez __len__(self)i inne „metody specjalne”
    • dodatkowe metody specjalne, które można uzyskać z innych metod specjalnych ( __add__oraz __iadd__dla +i +=)
    • self jako pierwszy parametr metody
    • możesz zapomnieć o wywołaniu konstruktora klasy podstawowej
    • brak modyfikatorów dostępu (prywatny, chroniony ...)
  • brak stałych definicji
  • brak niezmienności dla typów niestandardowych
  • GIL
  • słaba wydajność, która prowadzi do połączenia Pythona i C oraz problemy z kompilacjami (szukanie bibliotek C, zależności platformy ...)
  • zła dokumentacja, szczególnie w bibliotekach stron trzecich
  • niekompatybilność między Python 2.x a 3.x
  • słabe narzędzia do analizy kodu (w porównaniu do tego, co jest oferowane dla języków o typie statycznym, takich jak Java lub C #)
deamon
źródło
5
Osobiście uważam, że niekompatybilność między 2.x a 3.x jest jedną z największych zalet Pythona. Jasne, to także wada. Ale zuchwałość programistów, by przełamać wsteczną kompatybilność, oznacza również, że nie musieli nosić ze sobą cruft w nieskończoność. Więcej języków potrzebuje takiego przeglądu.
Konrad Rudolph,
0

„Niezmienność” nie jest dokładnie jego mocną stroną. Liczby, krotki i łańcuchy AFAIK są niezmienne, wszystko inne (tj. Obiekty) można modyfikować. Porównaj to z funkcjonalnymi językami, takimi jak Erlang lub Haskell, w których wszystko jest niezmienne (przynajmniej domyślnie).

Jednak niezmienność naprawdę świeci dzięki współbieżności *, która również nie jest mocną stroną Pythona, więc przynajmniej jest konsekwencją.

(* = Dla nitpickerów: mam na myśli współbieżność, która jest przynajmniej częściowo równoległa. Wydaje mi się, że Python jest w porządku z współbieżnością „jednowątkową”, w której niezmienność nie jest tak ważna. (Tak, miłośnicy FP, wiem, że niezmienność jest świetnie nawet bez współbieżności.))

Kosta
źródło
0

Chciałbym mieć wyraźnie równoległe konstrukcje. Częściej niż nie, kiedy piszę listę ze zrozumieniem

[ f(x) for x in lots_of_sx ]

Nie obchodzi mnie kolejność, w jakiej elementy będą przetwarzane. Czasami nawet mnie nie obchodzi, w jakiej kolejności są zwracane.

Nawet jeśli CPython nie może zrobić tego dobrze, gdy mój f jest czystym Pythonem, takie zachowanie można zdefiniować dla innych implementacji.

wariat
źródło
// spawn pęczek wątków // przekaż Que que do wszystkich wątków que.extend ([x dla x w Lot_of_sx]) que.wait () # Poczekaj, aż wszystkie partie_of_sx zostaną przetworzone przez wątki.
Zoran Pavlovic
0

Python nie ma optymalizacji wywołania ogona, głównie z powodów filozoficznych . Oznacza to, że rekurencja na dużych strukturach może kosztować pamięć O (n) (z powodu niepotrzebnego stosu, który jest utrzymywany) i będzie wymagać przepisania rekurencji jako pętli w celu uzyskania pamięci O (1).

a3nm
źródło