Was sind die Nachteile von Python? [geschlossen]

147

Python scheint heutzutage der letzte Schrei zu sein, und das nicht ohne Grund - denn es ist wirklich eine Sprache, mit der man gerne ein neues Problem löst. Aber, wie ein weiser Mann einmal sagte (nenne ihn nur einen weisen Mann , weil ich keine Ahnung habe, wer es tatsächlich sagte; nicht sicher, ob er überhaupt so weise war), um eine Sprache wirklich zu beherrschen, kennt man nicht nur ihre Syntax, Design usw., Vorteile, aber auch Nachteile. Keine Sprache ist perfekt, manche sind einfach besser als andere.

Also, was wären Ihrer Meinung nach objektive Nachteile von Python.

Hinweis: Ich bitte hier nicht um einen Sprachvergleich (dh C # ist besser als Python, weil ... yadda yadda yadda) - eher eine objektive (bis zu einem gewissen Grad) Meinung, welche Sprachfunktionen schlecht gestaltet sind, ob, was vielleicht einige fehlen dir und so weiter. Sie müssen eine andere Sprache als Vergleich verwenden, aber nur, um einen Punkt zu veranschaulichen, auf den sonst nur schwer einzugehen wäre (dh um das Verständnis zu erleichtern).

Rook
quelle
50
Ich denke, dass dies eine hilfreiche subjektive Frage ist, und es wäre eine Schande, sie zu schließen.
Eric Wilson
25
Hier scheint es einen Python-Fanboy zu geben, der einfach alle Anti-Python-Antworten herabstimmt.
Zvrba
2
@TMN: Dabei werden die Leerzeichen immer noch als Token behandelt, aber nicht zurückgegeben - und genau das macht Pythons Grammatik auch.
9
@ Roger: Die Konvention zu SO ist es, Abwertungen zu kommentieren. Da dies eine Seite für subjektive Meinungen ist, sehe ich keinen Grund für Ablehnungen. ohne Kommentare. Also stehe ich zu meiner "Namensgebung".
Zvrba
8
@zvrba: Downvotes bedeuten immer noch "nicht nützlich", genau wie immer.

Antworten:

109

Ich benutze Python ziemlich regelmäßig und halte es insgesamt für eine sehr gute Sprache. Trotzdem ist keine Sprache perfekt. Hier sind die Nachteile in der Reihenfolge ihrer Bedeutung für mich persönlich:

  1. Es ist langsam. Ich meine wirklich sehr, sehr langsam. Häufig spielt dies keine Rolle, aber es bedeutet definitiv, dass Sie für diese leistungskritischen Elemente eine andere Sprache benötigen.

  2. Verschachtelte Funktionen haben den Nachteil, dass Sie keine Variablen im äußeren Bereich ändern können. Bearbeiten: Ich verwende aufgrund der Bibliotheksunterstützung immer noch Python 2, und dieser Designfehler irritiert mich, aber anscheinend ist er in Python 3 aufgrund der nicht- lokalen Anweisung behoben . Ich kann es kaum erwarten, dass die von mir verwendeten Bibliotheken portiert werden, damit dieser Fehler endgültig auf den Aschehaufen der Geschichte geschickt werden kann.

  3. Es fehlen ein paar Funktionen, die für Bibliotheks- / generischen Code nützlich sein können, und IMHO ist die Einfachheit, die zu ungesunden Extremen führt. Die wichtigsten, an die ich denken kann, sind benutzerdefinierte Werttypen (ich vermute, diese können mit Metaklassen-Magie erstellt werden, aber ich habe es noch nie versucht) und ref-Funktionsparameter.

  4. Es ist weit vom Metall entfernt. Müssen Sie Threading-Primitive oder Kernel-Code schreiben oder so? Viel Glück.

  5. Obwohl es mir nichts ausmacht, dass ich semantische Fehler nicht im Voraus abfangen kann, um die Dynamik, die Python bietet, in Abrede zu stellen, wünschte ich mir, es gäbe eine Möglichkeit, syntaktische Fehler und dumme Dinge wie die falsche Eingabe von Variablennamen abzufangen, ohne den Code tatsächlich ausführen zu müssen.

  6. Die Dokumentation ist nicht so gut wie Sprachen wie PHP und Java, die einen starken Rückhalt im Unternehmen haben.

Dsimcha
quelle
60
@Casey, ich muss nicht zustimmen. Der Index ist schrecklich - versuchen Sie, die withAnweisung oder Methoden auf a nachzuschlagen list. Alles, was im Tutorial behandelt wird, ist grundsätzlich nicht durchsuchbar. Ich habe viel mehr Glück mit der Dokumentation von Microsoft für C ++.
Mark Ransom
17
Über 5 - verwenden Sie einfach Pyflakes. Es wurde geschrieben, um genau diese Fehler abzufangen.
Alexander Solovyov
4
Was die Geschwindigkeit anbelangt: Mit dem Aufstieg von PyPy können viele Python-Benutzer das Geschwindigkeitsproblem jetzt einfach mit einem Interpreter mit integriertem JIT-Compiler lösen (Python 3-Benutzer und Benutzer von C-Erweiterungsmodulen, die nicht von cpyext behandelt werden) habe diese Option nicht).
ncoghlan
29
Ich verachte die Python-Dokumente. Sie sind zwar hübscher als die meisten anderen, aber viele nützliche Informationen werden auf einer Seite zusammengefasst, z. B. Methoden für Zeichenfolgen und Listen - und alle Sequenztypen werden ebenfalls zusammengefasst. Wenn ich diese Informationen durchsuche, lande ich einfach auf einem riesigen Band und muss die Seite durchsuchen, um das zu finden, was ich will. Ich finde auch den Index auf diesen Seiten schwer zu lesen und es ist manchmal schwierig zu sagen, welchen Abschnitt ich möchte.
Carson Myers
5
Wie kann Distanz zum Metall ein Argument sein? Hat sich Python jemals als Systemsprache ausgegeben?
Mark Canlas
66

Ich hasse es, dass Python nicht zwischen Deklaration und Verwendung einer Variablen unterscheiden kann. Sie brauchen keine statische Eingabe, um dies zu erreichen. Es wäre einfach schön zu sagen, dass dies eine Variable ist, die ich absichtlich deklariere, und ich beabsichtige , einen neuen Namen einzuführen, dies ist kein Tippfehler.

Darüber hinaus verwende ich Python-Variablen normalerweise in einem einmal beschreibbaren Stil, dh, ich behandle Variablen als unveränderlich und ändere sie nicht nach ihrer ersten Zuweisung. Dank Funktionen wie dem Listenverständnis ist dies eigentlich unglaublich einfach und der Codefluss ist leichter zu verfolgen.

Ich kann diese Tatsache jedoch nicht dokumentieren. Nichts in Python hindert mich daran, Variablen zu überschreiben oder wiederzuverwenden.

Zusammenfassend möchte ich zwei Schlüsselwörter in der Sprache haben: varund let. Wenn ich in eine Variable schreibe, die von keiner dieser Variablen deklariert wurde, sollte Python einen Fehler auslösen. Außerdem letdeklariert Variablen als schreibgeschützt, während varVariablen "normal" sind.

Betrachten Sie dieses Beispiel:

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

Beachten Sie, dass die Typen immer noch implizit sind ( letVariablen sind jedoch in jeder Hinsicht statisch typisiert, da sie nicht auf einen neuen Wert zurückgeführt werden können, während varVariablen möglicherweise weiterhin dynamisch typisiert werden).

Schließlich sollten alle Methodenargumente automatisch let, dh schreibgeschützt sein. Es gibt im Allgemeinen keinen guten Grund, einen Parameter zu ändern, mit Ausnahme der folgenden Redewendung:

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

Dies könnte durch eine etwas andere Redewendung ersetzt werden:

def foo(bar = None):
    let mybar = bar or [1, 2, 3]
Konrad Rudolph
quelle
6
Ich wünschte, Python hätte eine "var" -Anweisung. Abgesehen von dem (sehr guten) Grund, den Sie angeben, würde dies auch das Lesen des Codes erheblich erleichtern, da Sie dann einfach die Seite durchsuchen können, um alle Variablendeklarationen zu erkennen.
jhocking
25
Es ist, als ob die Python-Entwickler die Lektionen der Vergangenheit ignoriert hätten. Variablen nicht zu deklarieren, Funktionen nicht zu deklarieren, ist ein Fehler, der erstmals in den 1950er Jahren begangen wurde. Die schwer zu findenden Bugs, die aus einem schwer zu entdeckenden Tippfehler resultierten, wurden erstaunlicherweise erst in den 1950er Jahren hergestellt. Dieser Sprachfehler wurde immer wieder gemacht (und später korrigiert). Das Deklarieren von Variablen ist keine große Belastung. Es hat meinen Hintern mehrmals gerettet. Ich arbeite unweigerlich use strict;und use warnings;in Perl an einem Skript beliebiger Größe. Python hat den Entwickler von viel zu vielen Debugging-Hilfen befreit.
David Hammen
19
@David, Um fair zu Python zu sein, wird eine Ausnahme ausgelöst, wenn Sie versuchen, auf eine Variable zuzugreifen, die nicht zugewiesen wurde. Viele der Sprachen, denen Deklarationen fehlen, würden eine Art Standardwert zurückgeben. Infolgedessen ist Pythons Version viel weniger problematisch als diese.
Winston Ewert
1
@yi_H Der Vorschlag sollte nicht abwärtskompatibel sein - oder sogar ein echter Vorschlag. Die Frage war, "was sind die Nachteile von Python" ... nun, nicht zu haben varund let(oder ein ähnlicher Mechanismus) ist ein Nachteil. Anders ausgedrückt: Wäre ich der Designer von Python gewesen, hätte ich so etwas getan. Dass sagte , zukünftige Versionen könnten diese enthalten , wenn Sie ein spezielles Paket laden (ähnlich __future__). Sprich import strict. Dies wird jedoch nicht passieren, da es syntaktische Hacks erfordert ...
Konrad Rudolph
3
+1 Für das Hinzufügen besserer "funktionaler" Programmierfähigkeiten.
Evan Plaice
44

Meine Hauptbeschwerde ist das Threading, das unter vielen Umständen (im Vergleich zu Java, C und anderen) aufgrund der globalen Interpretersperre nicht so performant ist (siehe "Inside the Python GIL" (PDF-Link) talk).

Es gibt jedoch eine Multiprozess-Schnittstelle , die sehr einfach zu verwenden ist. Sie wird jedoch die Speichernutzung für die gleiche Anzahl von Prozessen im Vergleich zu Threads erhöhen oder schwierig sein, wenn Sie viele gemeinsame Daten haben. Der Vorteil ist jedoch, dass ein Programm, das mit mehreren Prozessen arbeitet, über mehrere Computer skaliert werden kann, was mit einem Thread-Programm nicht möglich ist.

Ich bin mit der Kritik an der Dokumentation wirklich nicht einverstanden, ich denke, sie ist ausgezeichnet und besser als die meisten, wenn nicht alle wichtigen Sprachen.

Außerdem können Sie viele der Laufzeitfehler, auf denen pylint ausgeführt wird, abfangen .

Casey
quelle
2
+1 für Pylint. Ich wusste es nicht. Wenn ich das nächste Mal ein Projekt in Python mache, probiere ich es aus. Multithreading scheint auch gut zu funktionieren, wenn Sie Jython anstelle der Referenz-CPython-Implementierung verwenden. OTOH Jython ist etwas langsamer als CPython, daher kann dies den Zweck teilweise zunichte machen.
Dsimcha
3
Threading wird nicht gut unterstützt? Die Threading-Bibliotheken sind seit 2.1 dort.
rox0r
2
Ich weiß, dass es Threading-Unterstützung gibt, aber im Vergleich zu Java oder C wird die GIL Ihre Leistung wirklich verringern. Aus diesem Grund wird das Multiprocessing-Modul dem Threading vorgezogen.
cmcginty
2
Die Dokumentation ist gut, wenn Sie es schaffen, sie zu finden. Java-Klassen zu googeln ist viel einfacher als Python.
Brendan Long
@Casey Ich habe den Wortlaut in der Antwort geklärt, da Threading unterstützt wird, zeigt nur einige seltsame Leistung (einen Verweis und ein paar Links zu Dokumenten auch hinzugefügt)
dbr
28

Das Fehlen einer statischen Typisierung, die zu bestimmten Klassen von Laufzeitfehlern führen kann, ist die zusätzliche Flexibilität, die die Duck-Typisierung bietet, wohl nicht wert.

Jakob
quelle
5
Dies ist korrekt, obwohl es Tools wie PyChecker gibt, die einen Compiler in Sprachen wie C / Java auf Fehler überprüfen können.
Oliver Weiler
24
Dynamisches Tippen ist eine bewusste Designentscheidung, kein Nachteil.
Fehlender Faktor
14
Es ist dasselbe wie gesagt, Javas Schwäche ist der Mangel an dynamischer Typisierung.
MAK
12
@missingfaktor, @MAK, Entenschreiben war offensichtlich eine beabsichtigte Funktion. Die meisten Entwurfsentscheidungen bringen jedoch objektive Vor- und Nachteile mit sich. Die zusätzliche Codeflexibilität ist ein Vorteil der dynamischen Typisierung, und die zusätzlichen Klassen potenzieller Laufzeitfehler sind ein Nachteil. Der subjektive Teil ist, ob das Feature es wert ist.
Jacob
6
Die fehlende statische Typisierung erleichtert Programmierern das Schreiben von Code mit Laufzeitfehlern. int foo = 4; Console.Write(foo.Length);Kompiliert in C # nicht, daher kann der Fehler "Int32 hat keine Eigenschaft Länge" nicht versehentlich in veröffentlichte Software gelangen. In Python kann Code, der auf nicht vorhandene Elemente von Objekten zugreift, unentdeckt bleiben, bis er Laufzeitfehler verursacht, es sei denn, Sie führen optionale sekundäre Tools aus, um nach solchen Fehlern zu suchen.
Jacob
27

Ich denke, die objektorientierten Teile von Python fühlen sich irgendwie "angeschraubt" an. Das gesamte Erfordernis, "self" explizit an jede Methode weiterzugeben, ist ein Symptom dafür, dass die OOP-Komponente nicht ausdrücklich geplant war. Es zeigt auch Pythons manchmal kritische Regeln, die in einer anderen Antwort kritisiert wurden.

Bearbeiten:

Wenn ich sage, dass sich Pythons objektorientierte Teile "angeschraubt" anfühlen, meine ich, dass sich die OOP-Seite manchmal eher inkonsistent anfühlt. Nehmen wir zum Beispiel Ruby: In Ruby ist alles ein Objekt, und Sie rufen eine Methode mit der bekannten obj.methodSyntax auf (natürlich mit Ausnahme überladener Operatoren). in Python ist auch alles ein Objekt, aber einige Methoden, die Sie als Funktion aufrufen; Das heißt, Sie überladen __len__eine Länge, um sie zurückzugeben, nennen sie aber len(obj)statt der bekannteren (und konsistenteren) obj.lengthin anderen Sprachen. Ich weiß, dass es Gründe für diese Designentscheidung gibt, aber ich mag sie nicht.

Darüber hinaus fehlt dem OOP-Modell von Python jeglicher Datenschutz, dh es gibt keine privaten, geschützten und öffentlichen Mitglieder. Sie können sie mit _und __vor Methoden imitieren , aber es ist irgendwie hässlich. In ähnlicher Weise ist Python nicht ganz bekommt den Message-Passing - Aspekt des OOP Rechts, auch nicht .

Mipadi
quelle
17
Der Selbst Parameter wird nur machen explizit , welche andere Sprachen implizit verlassen. Diese Sprachen haben eindeutig einen "Selbst" -Parameter.
13
@ Roger Pate: Ja, aber dieses ausdrückliche Bedürfnis nach "Selbst" ist irgendwie ärgerlich (und ich würde argumentieren, eine undichte Abstraktion). Es kam auch nicht aus einer absichtlichen Designentscheidung, sondern aufgrund von Pythons "seltsamen" Regeln. Ich kann den Artikel nicht schnell finden, aber es gibt einen E-Mail-Post von Guido van Rossum, der genau erklärt, warum der Parameter "self" erforderlich ist.
Mipadi
2
@ Roger Pate: In objektorientierten Sprachen kann die Übergabe des Ziels als erster Parameter immer noch als Implementierungsdetail betrachtet werden. Mein Punkt ist jedoch nicht, ob es eine gute Idee ist oder nicht; Der Punkt ist, dass es in Python nicht auf eine bewusste Designentscheidung zurückzuführen ist, sondern darauf, Warzen im Scoping-System zu umgehen.
Mipadi
3
@mipadi: Das Update hat bessere Gründe (also werde ich die Abwertung entfernen), aber wenn Sie len als einen Operator betrachten, den Sie überladen, ist es in Python mehr OO. Würde gerne ein Beispiel oder eine Argumentation dazu sehen, wie Python die Nachrichtenübermittlung falsch macht.
8
Explizites Selbst ist ein Ergebnis der Tatsache, dass Methoden nur Funktionen sind (und, wie Winston bemerkte, implizite lokale Variablendeklarationen). Es steht Ihnen frei, diese Entwurfsentscheidung nicht zu mögen , aber OOP in einer Sprache "angeschraubt" zu nennen, in der zur Laufzeit alles als Objekt zugänglich ist, ist albern.
ncoghlan
19

Dinge, die ich an Python nicht mag:

  1. Threading (Ich weiß, es wurde bereits erwähnt, aber erwähnenswert in jedem Beitrag).
  2. Keine Unterstützung für mehrzeilige anonyme Funktionen ( lambdakann nur einen Ausdruck enthalten).
  3. Fehlen einer einfachen, aber leistungsstarken Eingabelesefunktion / -klasse (wie cinoder scanfin C ++ und C oder Scannerin Java).
  4. Alle Zeichenfolgen sind nicht standardmäßig Unicode (sondern in Python 3 behoben).
MAK
quelle
5
In Bezug auf (2) denke ich, dass dies durch die Möglichkeit verschachtelter Funktionen ausgeglichen wird.
Konrad Rudolph
3
@KonradRudolph Mein Hauptproblem bei verschachtelten Funktionen anstelle von mehrzeiligen Lambdas ist, dass die Lesereihenfolge vertauscht wird.
CookieOfFortune
2
@wkschwartz: raw_inputund 'sys.stdin' sind hübsche Barebones. Sie unterstützen nicht das Einlesen formatierter Eingaben (z. B. "% d:% d:% d"% (Stunde, Minute, Sekunde)). Bisher hat Python nichts, was an die Funktionalität von scanf (in C) oder Scanner (Java) heranreicht.
MAK
2
@limscoder: Alle Zeichenfolgen sind in Java standardmäßig Unicode. Ich sehe keinen guten Grund, separate str- und Unicode-Klassen zu haben. IMHO, Strings und Arrays von Bytes sollten nicht durch dieselbe Abstraktion dargestellt werden. Eine String-Klasse sollte zum Speichern und Bearbeiten von Text dienen - dessen interne Darstellung uns eigentlich egal ist. Wir sollten nicht möchten, dass an einem bestimmten Byte in einer Zeichenfolge abgeschnitten / ersetzt / gelöscht / eingefügt wird - wir möchten dies an einem bestimmten Zeichen tun . Es ist leicht, die Unterscheidung zu vergessen und Ihren Code in die Luft jagen zu lassen, wenn Sie nicht-englische Eingaben eingeben.
MAK
1
@limscoder: Wenn Sie einfachen Unicode sehen möchten, versuchen Sie es mit Tcl. Ich musste vor ein paar Jahren von Tcl zu Python wechseln, und mein Junge war überrascht, wie sehr die Unicode-Unterstützung von primitivem Python im Vergleich steht. Es ist in Tcl wirklich unsichtbar und ein großer Schmerz in Python.
Bryan Oakley
18

Standardargumente mit veränderlichen Datentypen.

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

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

Es ist normalerweise das Ergebnis einiger subtiler Fehler. Ich denke, es wäre besser, ein neues Listenobjekt zu erstellen, wenn ein Standardargument erforderlich wäre (anstatt ein einzelnes Objekt für jeden Funktionsaufruf zu erstellen).

Bearbeiten: Es ist kein großes Problem, aber wenn in den Dokumenten auf etwas verwiesen werden muss, bedeutet dies in der Regel, dass es ein Problem ist. Dies sollte nicht erforderlich sein.

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

Vor allem, wenn das der Standard sein sollte. Es ist nur ein seltsames Verhalten, das nicht mit dem übereinstimmt, was Sie erwarten, und das für eine große Anzahl von Umständen nicht nützlich ist.

Sternberg
quelle
Ich sehe viele Beschwerden darüber, aber warum besteht man darauf, dass eine leere Liste (die durch die Funktion geändert wird) als Standardargument verwendet wird? Ist das wirklich so ein großes Problem? Dh ist das ein echtes Problem?
Martin Vilcans
8
Es verstößt gegen den Grundsatz der geringsten Überraschung. Man würde nicht erwarten, dass die Parameter einer Funktion über Aufrufe hinweg überleben.
AIB
Es ist eine Folge davon, dass es eine Skriptsprache ist. Sie werden nur EINMAL von diesem Bug überrascht sein und nie wieder. Wenn Sie diesen Fehler selbst herausfinden, bekommen Sie einen Kick in den Hintern, um Sie daran zu erinnern, dass dies immer noch eine Skriptsprache ist. Und das nur, weil die Sprache so gut darin ist, den Skriptaspekt zu verbergen (vorausgesetzt, Sie verwenden ihn richtig).
Zoran Pavlovic
@ZoranPavlovic aus Neugier, warum ist das eine Folge davon, dass es sich um eine Skriptsprache handelt? Es scheint ein Problem zu sein, wenn die Daten gebunden sind und weil Listen veränderlich sind (zwei Dinge, die normalerweise gut sind, aber letztendlich schlecht, wenn sie zusammengefügt werden). Dasselbe Problem kann in einer Sprache auftreten, die kein Skript ist, wenn Sie die Daten zum Zeitpunkt der Funktionserstellung gebunden haben, anstatt bei jedem Funktionsaufruf eine neue Liste zu erstellen.
Sternberg
@aib: Ich glaube nicht, dass der Parameter hier wie bei jedem anderen Python-Objekt ein Zeiger auf ein Objekt ist. In diesem Fall ist das Objekt veränderlich und die Variable wird beim Deklarieren der Funktion gebunden. Der Parameter "überlebt über Aufrufe hinweg", aber was überlebt, ist der Verweis auf ein veränderbares Objekt.
Patrick Collins
14

Einige der Funktionen von Python, die es als Entwicklungssprache so flexibel machen, werden auch als Hauptnachteil der statischen Analyse angesehen, die beim Kompilieren und Verknüpfen in Sprachen wie C ++ und Java durchgeführt wird.

  • Implizite Deklaration lokaler Variablen

Lokale Variablen werden mit der normalen Zuweisungsanweisung deklariert. Dies bedeutet, dass Variablenbindungen in einem anderen Bereich eine explizite Annotation erfordern, die vom Compiler abgerufen werden muss (globale und nicht lokale Deklarationen für äußere Bereiche, Attributzugriffsnotation für Beispielbereiche). Dies reduziert die Anzahl der für die Programmierung erforderlichen Boilerplates erheblich, bedeutet jedoch, dass statische Analysetools von Drittanbietern (z. B. Pyflakes) erforderlich sind, um Prüfungen durchzuführen, die vom Compiler in Sprachen ausgeführt werden, die explizite Variablendeklarationen erfordern.

  • "Monkey Patching" wird unterstützt

Der Inhalt von Modulen, Klassenobjekten und sogar des eingebauten Namespaces kann zur Laufzeit geändert werden. Dies ist enorm leistungsfähig und ermöglicht viele äußerst nützliche Techniken. Diese Flexibilität bedeutet jedoch, dass Python einige Funktionen nicht bietet, die für statisch typisierte OO-Sprachen typisch sind. Insbesondere ist der Parameter "self" für Instanzmethoden eher explizit als implizit (da "Methoden" nicht in einer Klasse definiert werden müssen, können sie später durch Ändern der Klasse hinzugefügt werden, was bedeutet, dass dies nicht besonders praktisch ist implizite Übergabe der Instanzreferenz) und Attributzugriffskontrollen können nicht ohne weiteres erzwungen werden, je nachdem, ob sich der Code "innerhalb" oder "außerhalb" der Klasse befindet (da diese Unterscheidung nur während der Ausführung der Klassendefinition besteht).

  • Weit weg vom Metall

Dies gilt auch für viele andere Hochsprachen, aber Python tendiert dazu, die meisten Hardwaredetails zu abstrahieren. Systemprogrammiersprachen wie C und C ++ eignen sich noch weitaus besser für den direkten Hardwarezugriff (Python kann jedoch problemlos über CPython-Erweiterungsmodule oder portabler über die ctypesBibliothek mit diesen kommunizieren ).

ncoghlan
quelle
12
  1. Verwenden von Einrückungen für Codeblöcke anstelle von {} / begin-end.
  2. Jede neuere moderne Sprache hat einen angemessenen lexikalischen Geltungsbereich, aber nicht Python (siehe unten).
  3. Chaotische Dokumente (vergleiche mit der hervorragenden Perl5-Dokumentation).
  4. Zwangsjacke (es gibt nur einen Weg).

Beispiel für defektes Scoping; Abschrift der Dolmetschersitzung:

>>> 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

globalund nonlocalSchlüsselwörter sind eingeführt worden, um diese Entwurfsdummheit zu bessern.

zvrba
quelle
2
In Bezug auf das Scoping könnte es sich lohnen, auf python.org/dev/peps/pep-3104 zu schauen , um die Argumentation der aktuellen Methode zu verstehen.
Winston Ewert
Stimme mit +1 zu. Also +1.
Jas
34
Eine Möglichkeit zu haben, ist von Vorteil. Wenn Sie den Code einer anderen Person lesen, müssen Sie keine einzige Anweisung entschlüsseln. Sobald die Redewendungen in Ihrem Gehirn fest verdrahtet sind, sollten Sie sofort erkannt werden.
rox0r
9
Stimmen Sie voll und ganz mit @ rox0r überein. Die "Zwangsjacke" verhindert alle Arten von Syntaxkriegen.
Keithjgrant
8
Um ehrlich zu sein, benötige ich in Python sehr selten die Schlüsselwörter globaloder nonlocal. So selten, dass ich vergesse, dass dieses Problem besteht, und es ein paarmal neu googeln muss, obwohl ich jeden Tag bei der Arbeit Python-Code schreibe. Für mich ist Code, der globale Variablen (oder, schlimmer noch, äußere, nicht globale Variablen) modifizieren muss, ein Codegeruch. Es gibt normalerweise (nicht immer) einen besseren Weg.
Ben
11

Ich finde Pythons Kombination aus objektorientierter this.method()und prozeduraler / funktionaler method(this)Syntax sehr beunruhigend:

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

Dies ist besonders schlimm, da eine große Anzahl der Funktionen (anstatt der Methoden) nur in den globalen Namespace geschrieben werden : Methoden, die sich auf Listen, Zeichenfolgen, Zahlen, Konstruktoren und Metaprogramme beziehen, die alle in einer großen alphabetisch sortierten Liste zusammengefasst sind.

Zumindest haben funktionale Sprachen wie F # alle Funktionen, die ordnungsgemäß in Modulen benannt sind:

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

Sie sind also nicht alle zusammen. Darüber hinaus ist dies ein Standard, der in der gesamten Bibliothek befolgt wird, sodass er zumindest konsistent ist.

Ich verstehe die Gründe für die Funktion vs Methode Sache, aber ich denke immer noch, es ist eine schlechte Idee, sie so zu mischen. Ich wäre viel glücklicher, wenn die Methodensyntax befolgt würde, zumindest für die üblichen Operationen:

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

Unabhängig davon, ob die Methoden mutieren oder nicht, hat es mehrere Vorteile, sie als Methoden für das Objekt zu haben:

  • Einzelner Ort, um die "allgemeinen" Operationen für einen Datentyp nachzuschlagen: andere Bibliotheken / etc. Möglicherweise haben sie andere ausgefallene Dinge, die sie mit den Datentypen tun können, aber die "Standard" -Operationen sind alle in den Methoden des Objekts.
  • Sie müssen das nicht mehr wiederholen, Modulewenn Sie anrufen Module.method(x). Warum muss ich im obigen Funktionslisten-Beispiel immer wieder etwas sagen List? Es sollte wissen, dass es ein ist Listund ich möchte die Navigation.map()Funktion nicht darauf aufrufen ! Mit der x.map()Syntax bleibt es trocken und dennoch eindeutig.

Und natürlich hat es Vorteile gegenüber der Art und Weise , wie alles in einem globalen Namespace abgelegt wird . Es ist nicht so, dass der gegenwärtige Weg nicht in der Lage ist , Dinge zu erledigen. Es ist sogar ziemlich knapp ( len(lst)), da nichts mit einem Namensraum versehen ist! Ich verstehe die Vorteile der Verwendung von Funktionen (Standardverhalten usw.) gegenüber Methoden, aber es gefällt mir immer noch nicht.

Es ist nur chaotisch. Und in großen Projekten ist Unordnung Ihr schlimmster Feind.

Haoyi
quelle
1
Ja ... Ich vermisse den LINQ-Stil (ich bin sicher, dass LINQ nicht der erste ist, der ihn implementiert, aber ich bin am besten mit ihm vertraut).
CookieOfFortune
1
Stellen Sie sich len (x) nicht als Methode vor. "len" ist eine Funktion. Python hat Funktionen und Methoden und ich sehe nichts falsch an diesem Ansatz. Das Fehlen geeigneter Funktionen ist in der Regel die Ursache für unnötiges Tippen.
Rbanffy
Ich weiß, len()ist eine Funktion, und was sind die Vorteile. Ich erklärte auch, warum ich denke, dass es eine schlechte Idee ist, warum ich denke, dass die globalen Funktionen eine besonders schlechte Idee sind, und warum ich denke, dass Methoden eine bequeme Methode zum Organisieren und Ermitteln Ihrer Funktionalität darstellen =)
Haoyi
Ich glaube nicht, dass 42 (oder 43?) Keywords eine "große" Zahl sind. Dazu gehören auch Dinge wie def, classund andere Nicht-Funktionsaufrufe. Vergleichen Sie das mit 100+ in den meisten anderen populären Sprachen. Bedenken Sie auch die Linie von import this: Namespaces are one honking great idea -- let's do more of those!. Ich denke, Sie könnten Python-Namespaces falsch verstehen;)
Wayne Werner
8

Mangel an Homoikonizität .

Python musste darauf warten, dass 3.x ein "with" -Stichwort hinzufügte. In jeder homoikonischen Sprache könnte es trivial in eine Bibliothek aufgenommen worden sein.

Die meisten anderen Probleme, die ich in den Antworten gesehen habe, sind einer von drei Arten:

1) Dinge, die mit Werkzeugen repariert werden können (z. B. Pyflakes) 2) Implementierungsdetails (GIL, Leistung) 3) Dinge, die mit Codierungsstandards repariert werden können (dh Features, von denen man wünscht, sie wären nicht da)

# 2 ist kein Problem mit der Sprache, IMO # 1 und # 3 sind keine ernsthaften Probleme.

Aidenn
quelle
1
withwar von Python 2.5 mit verfügbar from __future__ import with_statement, aber ich stimme zu, ich fand es gelegentlich bedauerlich, dass Aussagen wie if/ for/ print/ etc "speziell" statt regulärer Funktionen sind
dbr
7

Python ist meine Lieblingssprache, da es sehr ausdrucksstark ist, aber Sie trotzdem davon abhält, zu viele Fehler zu machen. Ich habe noch ein paar Dinge, die mich nerven:

  • Keine echten anonymen Funktionen. Lambda kann für Funktionen mit nur einer withAnweisung verwendet werden , und die Anweisung kann für viele Dinge verwendet werden, bei denen Sie einen Codeblock in Ruby verwenden würden. Aber in manchen Situationen sind die Dinge etwas ungeschickter, als sie sein müssten. (Weit davon entfernt, so ungeschickt wie es in Java sein würde, aber immer noch ...)

  • Einige Verwirrung in der Beziehung zwischen Modulen und Dateien. Das Ausführen von "python foo.py" über die Befehlszeile unterscheidet sich von "import foo". Relative Importe in Python 2.x können ebenfalls Probleme verursachen. Dennoch sind Pythons Module viel besser als die entsprechenden Funktionen von C, C ++ und Ruby.

  • Explizit self. Obwohl ich einige der Gründe dafür verstehe und Python täglich verwende, mache ich den Fehler, es zu vergessen. Ein weiteres Problem dabei ist, dass es ein bisschen langweilig wird, eine Klasse aus einem Modul zu erstellen. Explizites Selbst hängt mit dem begrenzten Umfang zusammen, über den sich andere beschwert haben. Der kleinste Bereich in Python ist der Funktionsumfang. Wenn Sie Ihre Funktionen klein halten, wie Sie sollten, ist das kein Problem für sich und IMO liefert häufig saubereren Code.

  • Einige globale Funktionen, z. B. leneine Methode, von der Sie erwarten würden, dass sie sich hinter den Kulissen befindet.

  • Signifikante Einrückung. Nicht die Idee selbst, die ich großartig finde, aber da dies die einzige Sache ist, die so viele Leute davon abhält, Python auszuprobieren, wäre Python vielleicht mit einigen (optionalen) Anfangs- / Endesymbolen besser dran. Wenn ich diese Leute ignoriere, könnte ich auch mit einer erzwungenen Größe für den Einzug leben.

  • Dass es nicht die eingebaute Sprache von Webbrowsern ist, sondern JavaScript.

Von diesen Beschwerden ist es nur die allererste, die mir so wichtig ist, dass ich denke, dass sie der Sprache hinzugefügt werden sollten. Die anderen sind eher geringfügig, bis auf die letzte, was großartig wäre, wenn es passieren würde!

Martin Vilcans
quelle
+1 Ich frage mich, ob ich schreiben soll, datetime.datetime.now()wenn ein Projekt schreiben datetime.nowund dann zwei Projekte mischen kann, um es auf die eine Art und Weise zu schreiben, und dies wäre in Java sicherlich nicht geschehen, wenn ein Modul nicht den gleichen Namen wie eine Datei hätte (?) Wenn Sie sehen, wie auf die übliche Weise das Modul uns mit der Datei zu verwechseln scheint, wenn beide Verwendungen geübt und explizit sind, selfversuche ich immer noch zu verstehen, da die Aufrufe nicht die gleiche Anzahl von Argumenten wie die Funktionen haben. Und Sie könnten denken, dass die VM-Python langsam ist?
Niklas Rosencrantz
Bezüglich Ihres Problems mit dem expliziten Selbstschlüsselwort. Könnte ich vorschlagen, eine gute Python-IDE dafür zu verwenden? Ich weiß, dass PyDev in Eclipse den Selbstteil einer Funktionssignatur automatisch vervollständigt, wenn festgestellt wird, dass Sie in einer Klasse schreiben.
Zoran Pavlovic
5

Python ist noch nicht ausgereift: Die Sprache Python 3.2 weist derzeit Kompatibilitätsprobleme mit den meisten derzeit verteilten Paketen auf (normalerweise sind sie mit Python 2.5 kompatibel). Dies ist ein großer Nachteil, der derzeit mehr Entwicklungsaufwand erfordert (Finden des benötigten Pakets; Überprüfen der Kompatibilität; Wiegen der Auswahl eines nicht so guten Pakets, das möglicherweise kompatibler ist; Verwenden der besten Version; Aktualisieren auf 3.2, was dann Tage dauern könnte) anfangen, etwas Nützliches zu tun).

Voraussichtlich Mitte 2012 wird dies weniger nachteilig sein.

Beachten Sie, dass ich wohl von einem Fan-Boy abgewertet wurde. Während einer Entwicklerdiskussion kam unser hochrangiges Entwicklerteam jedoch zu dem gleichen Ergebnis.

Reife bedeutet, dass ein Team die Technologie nutzen und ohne versteckte Risiken (einschließlich Kompatibilitätsprobleme) sehr schnell einsatzbereit ist. Python-Pakete von Drittanbietern und viele Apps funktionieren heutzutage bei den meisten Paketen nicht unter 3.2. Dies schafft mehr Arbeit für die Integration, das Testen und die Neuimplementierung der Technologie selbst, anstatt das vorliegende Problem zu lösen == weniger ausgereifte Technologie.

Update für Juni 2013: Python 3 hat immer noch Laufzeitprobleme. Von Zeit zu Zeit erwähnt ein Teammitglied ein erforderliches Paket und sagt dann "außer es ist nur für 2.6" Unsere Werkzeuge bleiben bei 3.2). Nicht einmal MoinMoin, das reine Python-Wiki, ist in Python 3 geschrieben.

Jonathan Cline IEEE
quelle
2
Ich stimme Ihnen nur zu, wenn Ihre Definition der Fälligkeit nicht mit einer Version kompatibel ist, die vom Design her nicht kompatibel ist .
Tshepang
3
Ich stimme zu, dass die beiden inkompatiblen Streams von Python ein Problem darstellen (obwohl verständlich, warum dies geschehen ist), aber ich sehe das nicht als ein Problem der "Reife".
Winston Ewert
In gewisser Hinsicht bedeutet Reife, dass ein Team die Technologie nutzen und ohne versteckte Risiken (einschließlich Kompatibilitätsproblemen) sehr schnell einsatzbereit ist. Python-Pakete von Drittanbietern und viele Apps funktionieren heutzutage bei den meisten Paketen nicht unter 3.2. Dies schafft mehr Arbeit für die Integration, das Testen und die Neuimplementierung der Technologie selbst, anstatt das vorliegende Problem zu lösen == weniger ausgereifte Technologie.
Jonathan Cline IEEE
2
Dann verwenden Sie einfach Python 2.x. Weißt du ... die Version, die jeder benutzt. Oder lesen Sie die Paketdokumentation für 2 Sekunden, um herauszufinden, mit welchen Versionen es kompatibel ist.
Sternberg
2
"Nur weil Python 3.0 für einige Zeit veröffentlicht wurde, heißt das noch lange nicht, dass es die Version ist, die Sie verwenden sollten. Python 3.0 und 2.x werden zur gleichen Zeit entwickelt. Ich hoffe, dass wir in Zukunft alle in der Lage sein werden, es zu verwenden." Python 3.0, aber für den Moment ist die Verwendung von 2.x eine gute Lösung. "-> Das ist eine 500-Zeichen-Methode: Es ist noch nicht ausgereift.
Jonathan Cline IEEE
4

Der Umfang von Python ist sehr schlecht, was die objektorientierte Programmierung in Python sehr umständlich macht.

Mason Wheeler
quelle
8
Kannst du ein Beispiel geben? (Ich bin sicher, Sie haben Recht, aber ich möchte ein Beispiel)
Winston Ewert
24
Ich mag Python, aber ich hasse es unbedingt , self.vor jedem Verweis auf eine Instanzeigenschaft und -methode stehen zu müssen. Es macht es unmöglich, mit Python eine DSL zu erstellen, wie es in Ruby so einfach ist.
Adam Crossland
35
Ich finde das Selbst nicht peinlich, ich mag die explizite Aussage.
Winston Ewert
9
Ich verstehe nicht, was die große Sache mit dem expliziten Selbst ist. In C ++, Java und D werden Member-Variablen häufig ohnehin durch Konventionen explizit angegeben, indem ihnen beispielsweise ein Unterstrich vorangestellt wird.
Dsimcha
7
Sie verwenden self in Methoden, die sich von ihrer Deklaration unterscheiden: def foo (self) aber self.foo (). Ich finde diese Mischung aus expliziter Definition, aber implizitem Blick hinter die Kulissen nicht besonders hübsch.
LennyProgrammers
4

Meine Griffe über Python:

  • Angeschraubte OOP (Siehe @ mipadis Antwort zur Erarbeitung dieser Frage)
  • Fehlerhafte Implementierung von Lambdas
  • Umfangsprobleme
  • Keine persistenten Sammlungen in der Standardbibliothek
  • Schlechte Eignung für eingebettete DSLs
Fehlender Faktor
quelle
Warum die Gegenstimme?
Fehlender Faktor
Ich bin nicht der Abwähler, aber kannst du erklären, warum du denkst, dass der OO angeschraubt ist? Python hatte schon immer OO, es ist ein Kernteil der Sprache.
Daenyth
Siehe @ mipadis Antwort.
Fehlender Faktor
4

Zugriffsmodifikatoren in Python können nicht erzwungen werden - dies erschwert das Schreiben von gut strukturiertem, modularisiertem Code.

Ich nehme an, das ist Teil von @ Masons kaputtem Scoping - ein großes Problem im Allgemeinen mit dieser Sprache. Für Code, der lesbar sein soll, scheint es ziemlich schwierig zu sein, herauszufinden, welcher Umfang und welcher Wert zu einem bestimmten Zeitpunkt vorhanden sein kann und sollte - ich denke derzeit aufgrund dieser Nachteile darüber nach, von der Python-Sprache abzuweichen .

Nur weil "wir alle Erwachsenen zustimmen", heißt das nicht, dass wir keine Fehler machen und in einer starken Struktur nicht besser arbeiten, besonders wenn wir an komplexen Projekten arbeiten - Einrückungen und bedeutungslose Unterstriche scheinen nicht ausreichend zu sein .

Mikey
quelle
Das Fehlen von Zugriffskontrollen ist also schlecht ... aber das explizite Scoping von Variablenschreibvorgängen in einen nicht lokalen Namespace ist auch schlecht?
ncoghlan
@ncoghlan: 1 - Diese Funktion ist in vielen modernen Sprachen Standard, je nachdem, wie Sie Ihr Projekt konfigurieren. 2 -Es ist unter der Kontrolle des Programmierers. 3 - nicht sicher, was daran so toll ist - Sie können Ihren Bereich mit ein paar Projekteinstellungen in den meisten kompilierten Sprachen / IDEs problemlos steuern. Wenn "wir alle Erwachsenen zustimmen", sollten wir in der Lage sein, unsere eigenen Entscheidungen zu treffen und den Umfang an unser besonderes Komfortniveau anzupassen.
Vector
2
Die Leute, die nach "erzwungenen Zugriffskontrollen" fragen, fordern uns auf, eines der Dinge herauszunehmen, die Python so großartig machen: Es ist absichtlich schwierig für Entwickler, zu kontrollieren, wie ihr Code später verwendet wird. Wie viel von der Boilerplate in C ++ und Java-Mustern dient ausschließlich der Umgehung der erzwungenen Zugriffskontrollen? Ich kann definitiv verstehen, dass Leute sich aus diesen Gründen gegen Python entscheiden, aber die statische Durchsetzung wird niemals einen Ersatz für strenge Tests darstellen.
ncoghlan
1
@ncoghlan - für mich sind die großen Dinge an Python Eleganz der Syntax und Prägnanz - Ausdruckskraft. Und wie ich bereits sagte, hat Scoping weniger damit zu tun, dass Programmierer mit Dingen herumspielen, die sie nicht sollten, als mit der Codestruktur und -organisation. Das Konzept der Einwilligung von Erwachsenen ist daher umstritten. Ich arbeite an komplexen Projekten, nicht an einfachen Dienstprogrammen und Skripten - der Code muss sorgfältig modularisiert und strukturiert sein - Zugriffsmodifikatoren sind eine der wichtigsten Möglichkeiten, dies sicherzustellen.
Vector
1
Und Code-Überprüfung, Training und Kopplungsanalyse sind andere. Für mich fallen erzwungene Zugriffskontrollen in den gleichen Bereich wie die statische Eingabe: Sie tragen zwar dazu bei, ein gewisses zusätzliches Vertrauen in die Korrektheit zu schaffen (was jedoch nicht ausreicht, um umfangreiche Tests zu vermeiden), verursachen jedoch hohe Kosten für die Entwicklungsproduktivität. (Auf praktischer Ebene passen die Zugriffssteuerungen für Klassenattribute auch nicht zum Python-Objektmodell, bei dem Methoden nur gewöhnliche Funktionen sind, die aus Klassen abgerufen wurden. Die "Innen- / Außen" -Grenze für Klassen existiert nicht wirklich, kann es also nicht sein erzwungen)
ncoghlan
3
  1. Die leistung ist nicht gut, aber verbessert sich mit pypy,
  2. Die GIL verhindert die Verwendung von Threading zur Beschleunigung des Codes (obwohl dies normalerweise eine vorzeitige Optimierung ist).
  3. Es ist nur für die Anwendungsprogrammierung nützlich,

Aber es hat einige großartige Einlösungsfunktionen:

  1. Es ist perfekt für RAD,
  2. Es ist einfach, mit C zu kommunizieren (und für C einen Python-Interpreter einzubetten),
  3. Es ist sehr lesbar,
  4. Es ist leicht zu lernen,
  5. Es ist gut dokumentiert,
  6. Batterien sind im Lieferumfang enthalten, die Standardbibliothek ist riesig und pypi enthält Module für praktisch alles,
  7. Es hat eine gesunde Gemeinschaft.
dan_waterworth
quelle
Was hat Sie dazu inspiriert, die Vorteile zu erwähnen? Die Frage nach den Problemen. Wie auch immer, was meinst du damit, dass es nur für die Anwendungsprogrammierung nützlich ist? Welche andere Programmierung gibt es? Wofür genau ist es nicht gut?
Tshepang
5
Ich habe die Vorteile aufgelistet, weil ich denke, dass sie die Nachteile überwiegen. Haben Sie jemals versucht, ein Linux-Kernel-Modul in Python zu implementieren?
Dan_waterworth
3

Ich bevorzuge Python, und der erste Nachteil, der mir einfällt, ist, dass Sie beim Auskommentieren einer Anweisung wie if myTest():dieser den Einzug des gesamten ausgeführten Blocks ändern müssen, was Sie mit C oder Java nicht tun müssten. Tatsächlich habe ich in Python angefangen, eine if-Klausel zu kommentieren, anstatt sie auszukommentieren: `if True: #myTest (), damit ich nicht auch den folgenden Codeblock ändern muss. Da Java und C nicht auf Einrückungen angewiesen sind, wird das Auskommentieren von Anweisungen mit C und Java erleichtert.

Niklas Rosencrantz
quelle
1
Sie würden ernsthaft C- oder Java-Code bearbeiten, um die Blockebene eines Codes zu ändern, ohne dessen Einrückung zu ändern?
Ben
4
@Ben Vorübergehend ja ...
Alternative
1
@ben gleich hier.
Christopher Mahan
2
Ich benutze den Trick des Wechsels if something()zu if False and something(). Ein weiterer Trick ist das Auskommentieren mit einer mehrzeiligen Zeichenfolge.
Martin Vilcans
1
@ Martin natürlich! if False ...
Christopher Mahan
3

Der Mehrfachversand lässt sich nicht gut in das etablierte Einzelversandsystem integrieren und ist nicht sehr leistungsfähig.

Das dynamische Laden ist ein großes Problem in parallelen Dateisystemen, in denen POSIX-ähnliche Semantiken zu katastrophalen Verlangsamungen für metadatenintensive Vorgänge führen. Ich habe Kollegen, die eine Viertelmillion Kernstunden damit verbracht haben, Python (mit numpy, mpi4py, petsc4py und anderen Erweiterungsmodulen) auf 65k-Kernen zu laden. (Die Simulation lieferte bedeutende neue wissenschaftliche Ergebnisse, es hat sich also gelohnt, aber es ist ein Problem, wenn mehr als ein Barrel Öl verbrannt wird, um Python einmal zu laden.) Die Unfähigkeit, statisch zu verknüpfen, hat uns gezwungen, uns an große Verrenkungen zu gewöhnen angemessene Ladezeiten im Maßstab, einschließlich des Patchens von libc-rtld, um dlopeneinen kollektiven Dateisystemzugriff durchzuführen.

Jed
quelle
Wow, scheint sehr technisch, haben Sie Referenzmaterial, Beispiele, Blogposts oder Artikel zu diesem Thema? Ich frage mich, ob ich in naher Zukunft solchen Fällen ausgesetzt sein könnte.
Vincent
Aron hielt einen Vortrag auf der SciPy 2012 . Das dlopenZeug befindet sich in unserer Collfs- Bibliothek. Dieses Repository enthält auch zusätzliche Zipimport-Tricks, die von Asher Langtons Pfad-Caching inspiriert wurden. Wir arbeiten an einer besseren Verteilung und einem Papier.
Jed
3
  • Eine ganze Reihe von sehr gängigen Bibliotheken und Software von Drittanbietern, die weit verbreitet sind, sind nicht ganz pythonisch. Einige Beispiele: Soaplib, Openerp, Reportlab. Kritik ist unangebracht, da, weit verbreitet, aber sie verwirrt die Python-Kultur (sie verletzt das Motto "Es sollte einen - und am besten nur einen - offensichtlichen Weg geben, dies zu tun"). Bekannte pythonische Erfolge (wie Django oder Trac) scheinen die Ausnahme zu sein.
  • Die potenziell unbegrenzte Abstraktionstiefe von Instanz, Klasse und Metaklasse ist konzeptionell wunderschön und einzigartig. Aber um es zu beherrschen, muss man den Interpreter genau kennen (in welcher Reihenfolge der Python-Code interpretiert wird usw.). Es ist nicht weithin bekannt und wird nicht richtig verwendet, während ähnliche schwarze Magie wie C # -Generika, die konzeptionell komplexer ist (IMHO), proportional weithin bekannt und verwendet zu sein scheint.
  • Um ein gutes Verständnis für das Gedächtnis und das Threading-Modell zu bekommen, müssen Sie mit Python vertraut sein, da es keine umfassenden Spezifikationen gibt. Sie wissen einfach, was funktioniert, vielleicht, weil Sie die Quellen des Dolmetschers oder erfahrene Macken gelesen und herausgefunden haben, wie man sie behebt. Zum Beispiel gibt es nur starke oder schwache Referenzen, nicht die Soft- und Phantom-Refs von Java. Java hat einen Thread für die Garbage Collection, während es keine formelle Antwort gibt, wann die Garbage Collection in Python stattfindet. Sie können einfach beobachten, dass die Garbage Collection nicht stattfindet, wenn kein Python-Code ausgeführt wird, und schließen daraus, dass dies möglicherweise manchmal passiert, wenn versucht wird, Speicher zuzuweisen. Kann schwierig sein, wenn Sie nicht wissen, warum eine gesperrte Ressource nicht freigegeben wurde (meine Erfahrung dazu war mod_python in freeswitch).

Wie auch immer, Python ist seit 4 Jahren meine Hauptsprache. Fanboys, Elitisten oder Monomanen zu sein, ist kein Teil der Python-Kultur.

Vincent
quelle
+1. Spec für Speicher und Threading-Modell ist direkt an. Aber FWIW, der Java-Garbage-Collector, der sich in einem Thread befindet (und fast alles andere über den GC), ist kein Aspekt der Java-Sprache oder der VM-Spezifikationen an sich, sondern eine Frage der Implementierung einer bestimmten JVM. Die Haupt-JVM von Sun / Oracle ist jedoch ausführlich in Bezug auf das Verhalten und die Konfigurierbarkeit von GCs dokumentiert, sofern ganze Bücher über die JVM-Optimierung veröffentlicht wurden. Theoretisch könnte man CPython auf dieselbe Weise dokumentieren, unabhängig von der Sprachspezifikation.
Andrew Janke
2
  • Seltsame OOP:
    • len(s)durch __len__(self)und andere "spezielle Methoden"
    • Extra spezielle Methoden, die von anderen speziellen Methoden ( __add__und __iadd__für +und +=) abgeleitet werden könnten
    • self als erster Methodenparameter
    • Sie können vergessen, den Basisklassenkonstruktor aufzurufen
    • keine Zugriffsmodifikatoren (privat, geschützt ...)
  • keine konstanten Definitionen
  • Keine Unveränderlichkeit für benutzerdefinierte Typen
  • Gil
  • schlechte Performance, die zu einer Mischung aus Python und C führt und Probleme mit Builds hat (Suche nach C-Bibliotheken, Plattformabhängigkeiten ...)
  • schlechte Dokumentation, insbesondere in Drittanbieter-Bibliotheken
  • Inkompatibilität zwischen Python 2.x und 3.x.
  • schlechte Code-Analyse-Tools (im Vergleich zu dem, was für statisch typisierte Sprachen wie Java oder C # angeboten wird)
deamon
quelle
5
Persönlich denke ich, dass Inkompatibilität zwischen 2.x und 3.x einer der größten Vorteile von Python ist. Klar, das ist auch ein Nachteil. Die Kühnheit der Entwickler, die Abwärtskompatibilität zu brechen, bedeutet aber auch, dass sie Cruft nicht endlos herumtragen müssen. Mehr Sprachen brauchen eine solche Überarbeitung.
Konrad Rudolph
0

"Unveränderlichkeit" ist nicht gerade die Stärke. AFAIK-Zahlen, Tupel und Strings sind unveränderlich, alles andere (dh Objekte) ist veränderlich. Vergleichen Sie das mit funktionalen Sprachen wie Erlang oder Haskell, in denen alles unveränderlich ist (zumindest standardmäßig).

Unveränderlichkeit strahlt jedoch wirklich wirklich mit Parallelität * aus, was auch nicht Pythons Stärke ist, also zumindest konsequent.

(* = Für die Nitpicker: Ich meine Parallelität, die zumindest teilweise parallel ist. Ich denke, Python ist in Ordnung mit "single-threaded" Parallelität, in der Unveränderlichkeit nicht so wichtig ist. (Ja, FP-Liebhaber, ich weiß, dass Unveränderlichkeit ist toll auch ohne nebenläufigkeit.))

Kosta
quelle
0

Ich hätte gerne explizit parallele Konstrukte. Meistens, wenn ich eine Liste wie Verständnis schreibe

[ f(x) for x in lots_of_sx ]

Es ist mir egal, in welcher Reihenfolge die Elemente verarbeitet werden. Manchmal ist es mir sogar egal, in welcher Reihenfolge sie zurückgegeben werden.

Auch wenn CPython es nicht gut kann, wenn mein f reines Python ist, könnte ein solches Verhalten für andere Implementierungen definiert werden.

rbanffy
quelle
// Thread-Bündel erzeugen // Queue-Queue an alle Threads übergeben que.extend ([x für x in lots_of_sx]) que.wait () # Warten Sie, bis alle lots_of_sx von Threads verarbeitet wurden.
Zoran Pavlovic
0

Python hat keine Tail-Call-Optimierung, hauptsächlich aus philosophischen Gründen . Dies bedeutet, dass die Schwanzrekursion bei großen Strukturen O (n) Speicher kosten kann (aufgrund des unnötigen Stapels, der beibehalten wird), und Sie müssen die Rekursion als Schleife neu schreiben, um O (1) Speicher zu erhalten.

a3nm
quelle