Python vs C ++: Auswahl des richtigen Tools für den Job

Python vs C ++: Auswahl des richtigen Tools für den Job

Sind Sie ein C-Entwickler, der Python mit C vergleicht? Siehst du Python an und fragst dich, worum es in der ganzen Aufregung geht? Fragen Sie sich, wie Python mit den Konzepten verglichen wird, die Sie bereits kennen? Oder haben Sie eine Wette darauf, wer gewinnen würde, wenn Sie C ++ und Python in einen Käfig sperren und sie gegeneinander antreten lassen würden? Dann ist dieser Artikel genau das Richtige für Sie!

In this article, you’ll learn about:

  • Unterschiede und Ähnlichkeiten beim Vergleich von Python mit C ++

  • Zeiten, in denen Python die bessere Wahl für ein Problem ist und umgekehrt

  • Ressourcen, an die Sie sich wenden können, wenn Sie beim Erlernen von Python Fragen haben

Dieser Artikel richtet sich an C-Entwickler, die Python lernen. Es setzt Grundkenntnisse in beiden Sprachen voraus und verwendet Konzepte ab Python 3.6 und höher sowie C11 oder höher.

Schauen wir uns Python vs C ++ an!

Free Bonus:Click here to get access to a chapter from Python Tricks: The Book zeigt Ihnen die Best Practices von Python anhand einfacher Beispiele, die Sie sofort anwenden können, um schöneren + Pythonic-Code zu schreiben.

Sprachen vergleichen: Python vs C ++

Häufig finden Sie Artikel, die die Vorzüge einer Programmiersprache gegenüber einer anderen preisen. Sehr oft bemühen sie sich, eine Sprache zu fördern, indem sie die andere degradieren. Dies ist kein Artikel dieser Art.

Denken Sie beim Vergleich von Python mit C ++ daran, dass beide Tools verwendet werden und beide für unterschiedliche Probleme verwendet werden können. Denken Sie daran, einen Hammer und einen Schraubenzieher zu vergleichen. Siecouldverwenden einen Schraubendreher, um Nägel einzuschlagen, und Siecouldverwenden einen Hammer, um Schrauben einzudrücken, aber keine Erfahrung wird so effektiv sein.

Es ist wichtig, das richtige Werkzeug für den Job zu verwenden. In diesem Artikel erfahren Sie mehr über die Funktionen von Python und C, die sie für bestimmte Arten von Problemen zur richtigen Wahl machen. Betrachten Sie das "vs" in Python vs C also nicht als "gegen". Betrachten Sie es eher als Vergleich.

Kompilierung gegen virtuelle Maschine

Beginnen wir mit dem größten Unterschied, wenn Sie Python mit C vergleichen. In C verwenden Sie einen Compiler, der Ihren Quellcode in Maschinencode konvertiert und eine ausführbare Datei erstellt. Die ausführbare Datei ist eine separate Datei, die dann als eigenständiges Programm ausgeführt werden kann:

Compiling a C++ program for windows.

Dieser Prozess gibt die tatsächlichen Maschinenanweisungen für den spezifischen Prozessor und das Betriebssystem aus, für das er entwickelt wurde. In dieser Zeichnung handelt es sich um ein Windows-Programm. Dies bedeutet, dass Sie Ihr Programm separat für Windows, Mac und Linux neu kompilieren müssen:

Compiling a C++ program on three operating systems.

Sie müssen wahrscheinlich Ihren C ++ - Code ändern, um auch auf diesen verschiedenen Systemen ausgeführt zu werden.

Python verwendet dagegen einen anderen Prozess. Denken Sie jetzt daran, dass Sie sichCPython ansehen, die Standardimplementierung für die Sprache. Sofern Sie nichts Besonderes tun, ist dies der Python, den Sie ausführen.

Python wird jedes Mal ausgeführt, wenn Sie Ihr Programm ausführen. Es kompiliert Ihre Quelle genau wie der C ++ - Compiler. Der Unterschied besteht darin, dass Python anstelle von nativem Maschinencode zubytecode kompiliert. Bytecode ist der native Befehlscode fürPython virtual machine. Um nachfolgende Programmläufe zu beschleunigen, speichert Python den Bytecode in.pyc Dateien:

Python compiles a py file into a pyc file.

Wenn Sie Python 2 verwenden, finden Sie diese Dateien neben den.py-Dateien. Für Python 3 finden Sie sie im Verzeichnis__pycache__.

Der generierte Bytecode wird nicht nativ auf Ihrem Prozessor ausgeführt. Stattdessen wird es von der virtuellen Python-Maschine ausgeführt. Dies ähnelt der Java Virtual Machine oder der .NET Common Runtime Environment. Die erste Ausführung Ihres Codes führt zu einem Kompilierungsschritt. Anschließend wird der Bytecode so interpretiert, dass er auf Ihrer spezifischen Hardware ausgeführt wird:

Python compiles a py file into a pyc file and then executes it.

Solange das Programm nicht geändert wurde, überspringt jeder nachfolgende Lauf den Kompilierungsschritt und verwendet den zuvor kompilierten Bytecode zur Interpretation von:

Python executes a pyc file.

Das Interpretieren von Code ist langsamer als das Ausführen von nativem Code direkt auf der Hardware. Warum funktioniert Python so? Die Interpretation des Codes in einer virtuellen Maschine bedeutet, dass nur die virtuelle Maschine für ein bestimmtes Betriebssystem auf einem bestimmten Prozessor kompiliert werden muss. Der gesamte ausgeführte Python-Code wird auf jedem Computer mit Python ausgeführt.

Note: CPython ist in C geschrieben, sodass es auf den meisten Systemen mit einem C-Compiler ausgeführt werden kann.

Ein weiteres Merkmal dieser plattformübergreifenden Unterstützung ist, dass die umfangreiche Standardbibliothek von Python für alle Betriebssysteme geschrieben wurde.

Wenn Sie beispielsweisepathlib verwenden, werden Pfadtrennzeichen für Sie verwaltet, unabhängig davon, ob Sie Windows, Mac oder Linux verwenden. Die Entwickler dieser Bibliotheken haben viel Zeit damit verbracht, sie portabel zu machen, sodass Sie sich in Ihrem Python-Programm keine Sorgen machen müssen!

Bevor Sie fortfahren, sollten Sie zunächst eine Vergleichstabelle zwischen Python und C ++ verfolgen. Wenn Sie neue Vergleiche behandeln, werden sie kursiv hinzugefügt:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Nachdem Sie nun die Unterschiede in der Laufzeit beim Vergleich von Python mit C ++ festgestellt haben, wollen wir uns mit den Besonderheiten der Sprachsyntax befassen.

Syntaxunterschiede

Python und C ++ haben viele syntaktische Ähnlichkeiten, aber es gibt einige Bereiche, die es wert sind, diskutiert zu werden:

  • Leerzeichen

  • Boolesche Ausdrücke

  • Variablen und Zeiger

  • Verständnis

Beginnen wir zuerst mit dem umstrittensten: Leerzeichen.

Leerzeichen

Das erste, was die meisten Entwickler beim Vergleich von Python mit C bemerken, ist das "Whitespace-Problem". Python verwendet führende Leerzeichen, um den Bereich zu markieren. Dies bedeutet, dass der Körper eines "+ if +" - Blocks oder einer ähnlichen Struktur durch die Einrückungsstufe angezeigt wird. C verwendet geschweifte Klammern ({}), um dieselbe Idee anzuzeigen.

Während der Python-Lexer alle Leerzeichen akzeptiert, solange Sie konsistent sind, gibtPEP8 (official style guide für Python) 4 Leerzeichen für jede Einrückungsstufe an. Die meisten Editoren können so konfiguriert werden, dass dies automatisch erfolgt.

Es gab bereits eine enorme Anzahl vonwriting,shouting undranting zu Pythons Whitespace-Regeln. Lassen Sie uns also einfach über dieses Problem hinaus zu anderen Themen springen.

Anstatt sich auf einen lexikalischen Marker wie; zu verlassen, um jede Anweisung zu beenden, verwendet Python das Zeilenende. Wenn Sie eine Anweisung über eine einzelne Zeile erweitern müssen, können Sie den Backslash (\) verwenden, um dies anzuzeigen. (Beachten Sie, dass das Fortsetzungszeichen nicht benötigt wird, wenn Sie sich in Klammern befinden.)

Es gibt Menschen, die auf beiden Seiten des Whitespace-Problems unglücklich sind. Einige Python-Entwickler lieben es, dass Sie keine geschweiften Klammern und Semikolons eingeben müssen. Einige C ++ - Entwickler hassen das Vertrauen in die Formatierung. Zu lernen, mit beiden vertraut zu sein, ist die beste Wahl.

Nachdem Sie sich das Whitespace-Problem angesehen haben, gehen wir zu einem etwas weniger umstrittenen Thema über: Boolesche Ausdrücke.

Boolesche Ausdrücke

Die Art und Weise, wie SieBoolean expressions verwenden, ändert sich in Python gegenüber C geringfügig. In C können Sie zusätzlich zu den integrierten Werten numerische Werte verwenden, umtrue oderfalse anzugeben. Alles, was0 ergibt, wird alsfalse betrachtet, während jeder andere numerische Werttrue ist.

Python hat ein ähnliches Konzept, erweitert es jedoch um andere Fälle. Die Grundlagen sind ziemlich ähnlich. DiePython documentation geben an, dass die folgenden ElementeFalse ergeben:

  • Als falsch definierte Konstanten:

    • None

    • False

  • Nullen eines beliebigen numerischen Typs:

    • 0

    • 0.0

    • 0j

    • Decimal(0)

    • Fraction(0, 1)

  • Leere Sequenzen und Sammlungen:

    • ''

    • ()

    • []

    • {}

    • set()

    • range(0)

Alle anderen Elemente sindTrue. Das bedeutet, dass eine leere Liste[]False ist, während eine Liste, die nur null[0] enthält, immer nochTrue ist.

Die meisten Objekte werden zuTrue ausgewertet, es sei denn, das Objekt hat__bool__(), wasFalse zurückgibt, oder__len__(), was 0 zurückgibt. Auf diese Weise können Sie Ihre benutzerdefinierten Klassen erweitern, um als boolesche Ausdrücke zu fungieren.

Python hat auch in den Booleschen Operatoren einige geringfügige Änderungen gegenüber C. Für den Anfang erfordern die Anweisungen "+ if +" und "+ while +" nicht die umgebenden Klammern wie in C. Klammern können jedoch die Lesbarkeit verbessern. Verwenden Sie daher Ihr bestes Urteilsvermögen.

Die meisten Booleschen C ++ - Operatoren haben ähnliche Operatoren in Python:

C ++ - Operator Python-Operator

&&

and

`+

+`

or

!

not

&

&

`+

+`

`+

+`

Die meisten Operatoren ähneln C ++, aber wenn Sie auffrischen möchten, können SieOperators and Expressions in Python lesen.

Variablen und Zeiger

Wenn Sie Python nach dem Schreiben in C zum ersten Mal verwenden, denken Sie möglicherweise nicht viel über Variablen nach. Sie scheinen im Allgemeinen so zu funktionieren wie in C. Sie sind jedoch nicht gleich. Während Sie in C ++ Variablen verwenden, um Werte zu referenzieren, verwenden Sie in Python Namen.

Note: In diesem Abschnitt, in dem Sie Variablen und Namen in Python vs C betrachten, verwenden Sie * Variablen * für C undnames für Python. An anderer Stelle werden beide alsvariables bezeichnet.

Lassen Sie uns zunächst ein wenig zurücktreten und einen genaueren Blick auf Pythonsobject modelwerfen.

In Python isteverything ein Objekt. Zahlen werden in Objekten gehalten. Module werden in Objekten gehalten. Sowohl das Objekt einer Klasseandals auch die Klasse selbst sind Objekte. Funktionen sind auch Objekte:

>>>

>>> a_list_object = list()
>>> a_list_object
[]
>>> a_class_object = list
>>> a_class_object

>>> def sayHi(name):
...      print(f'Hello, {name}')
...
>>> a_function_object = sayHi
>>> a_function_object

Durch Aufrufen vonlist() wird ein neues Listenobjekt erstellt, das Siea_list_object zuweisen. Wenn Sie den Namen der Klasselist selbst verwenden, wird das Klassenobjekt beschriftet. Sie können einer Funktion auch eine neue Beschriftung hinzufügen. Dies ist ein mächtiges Werkzeug und wie alle mächtigen Werkzeuge kann es gefährlich sein. (Ich sehe dich an, Mr. Kettensäge.)

Note: Der obige Code wird inREPL ausgeführt, was für "Lesen, Auswerten, Druckschleife" steht. Diese interaktive Umgebung wird häufig verwendet, um Ideen in Python und anderen interpretierten Sprachen auszuprobieren.

Wenn Sie an einer Eingabeaufforderungpython eingeben, wird eine REPL angezeigt, in der Sie Code eingeben und selbst ausprobieren können!

Wenn Sie zur Diskussion Python vs C zurückkehren, beachten Sie, dass sich dieses Verhalten von dem in C unterscheidet. Im Gegensatz zu Python verfügt C ++ über Variablen, die einem Speicherort zugewiesen sind, und Sie müssen angeben, wie viel Speicher diese Variable verwenden wird:

int an_int;
float a_big_array_of_floats[REALLY_BIG_NUMBER];

In Python werden alle Objekte im Speicher erstellt und Sie weisen ihnen Beschriftungen zu. Die Beschriftungen selbst haben keine Typen und können auf jedem Objekttyp platziert werden:

>>>

>>> my_flexible_name = 1
>>> my_flexible_name
1
>>> my_flexible_name = 'This is a string'
>>> my_flexible_name
'This is a string'
>>> my_flexible_name = [3, 'more info', 3.26]
>>> my_flexible_name
[3, 'more info', 3.26]
>>> my_flexible_name = print
>>> my_flexible_name

Sie können jedem Objekttypmy_flexible_name zuweisen, und Python rollt einfach mit.

Wenn Sie Python mit C ++ vergleichen, kann der Unterschied zwischen Variablen und Namen etwas verwirrend sein, bietet jedoch einige hervorragende Vorteile. Zum einen haben Sie in Python keinepointers und müssen nie über Heap- oder Stack-Probleme nachdenken. Sie werden etwas später in diesem Artikel auf die Speicherverwaltung eingehen.

Verständnis

Python hat eine Sprachfunktion namenslist comprehensions. Es ist zwar möglich, Listenverständnisse in C ++ zu emulieren, aber es ist ziemlich schwierig. In Python sind sie ein grundlegendes Werkzeug, das Programmieranfängern beigebracht wird.

Eine Möglichkeit, über Listenverständnisse nachzudenken, besteht darin, dass sie wie ein überladener Initialisierer für Listen, Diktate oder Sätze sind. Mit einem iterierbaren Objekt können Sie eine Liste erstellen und dabei das Original filtern oder ändern:

>>>

>>> [x**2 for x in range(5)]
[0, 1, 4, 9, 16]

Dieses Skript beginnt mit dem iterierbarenrange(5) und erstellt eine Liste, die das Quadrat für jedes Element in der iterierbaren Datei enthält.

Es ist möglich, den Werten in der ersten Iterable Bedingungen hinzuzufügen:

>>>

>>> odd_squares = [x**2 for x in range(5) if x % 2]
>>> odd_squares
[1, 9]

Dasif x % 2 am Ende dieses Verständnisses begrenzt die verwendeten Zahlen vonrange(5) auf nur die ungeraden.

An diesem Punkt könnten Sie zwei Gedanken haben:

  1. Dies ist ein leistungsstarker Syntaxtrick, der einige Teile meines Codes vereinfacht.

  2. Sie können dasselbe in C ++ tun.

Es stimmt zwar, dass Sie in C ++vector der Quadrate der ungeraden Zahlen erstellen können, dies bedeutet jedoch normalerweise etwas mehr Code:

std::vector odd_squares;
for (int ii = 0; ii < 10; ++ii) {
    if (ii % 2) {
        odd_squares.push_back(ii);
    }
}

Für Entwickler, die aus Sprachen im C-Stil kommen, ist das Listenverständnis eine der ersten erkennbaren Möglichkeiten, wie siewrite more Pythonic code können. Viele Entwickler schreiben Python mit C ++ - Struktur:

odd_squares = []
for ii in range(5):
    if (ii % 2):
        odd_squares.append(ii)

Dies ist vollkommen gültiges Python. Es wird jedoch wahrscheinlich langsamer laufen und ist nicht so klar und präzise wie das Listenverständnis. Wenn Sie lernen, Listenverständnisse zu verwenden, wird nicht nur Ihr Code beschleunigt, sondern Ihr Code wird auch pythonischer und leichter zu lesen!

Note: Wenn Sie über Python lesen, sehen Sie häufig das WortPythonic, mit dem etwas beschrieben wird. Dies ist nur ein Begriff, den die Community verwendet, um Code zu beschreiben, der sauber und elegant ist und aussieht, als wäre er von einem Python-Jedi geschrieben worden.

Pythonsstd::algorithms

C ++ verfügt über eine Vielzahl von Algorithmen, die in die Standardbibliothek integriert sind. Python verfügt über ähnliche integrierte Funktionen, die denselben Bereich abdecken.

Das erste und leistungsstärkste davon ist dasin operator, das einen gut lesbaren Test bietet, um festzustellen, ob ein Element in einemlist,set oderdictionary enthalten ist:

>>>

>>> x = [1, 3, 6, 193]
>>> 6 in x
True
>>> 7 in x
False
>>> y = { 'Jim' : 'gray', 'Zoe' : 'blond', 'David' : 'brown' }
>>> 'Jim' in y
True
>>> 'Fred' in y
False
>>> 'gray' in y
False

Beachten Sie, dass der Operatorin bei Verwendung in Wörterbüchern nur nach Schlüsseln und nicht nach Werten testet. Dies wird durch den abschließenden Test'gray' in y gezeigt.

in kann mitnot kombiniert werden, um eine gut lesbare Syntax zu erhalten:

if name not in y:
    print(f"{name} not found")

Als nächstes steht in Ihrer Parade der in Python integrierten Operatorenany. Dies ist eine boolesche Funktion, dieTrue zurückgibt, wenn ein Element der angegebenen iterierbaren DateiTrue ergibt. Dies kann ein wenig albern erscheinen, bis Sie sich an Ihr Listenverständnis erinnern! Die Kombination dieser beiden kann in vielen Situationen zu einer leistungsstarken, klaren Syntax führen:

>>>

>>> my_big_list = [10, 23, 875]
>>> my_small_list = [1, 2, 8]
>>> any([x < 3 for x in my_big_list])
False
>>> any([x < 3 for x in my_small_list])
True

Schließlich haben Sieall, wasany ähnlich ist. Dies gibtTrueonly zurück, wenn - Sie haben es erraten -all der Elemente in der IterableTrue sind. Die Kombination mit Listenverständnis führt wiederum zu einer leistungsstarken Sprachfunktion:

>>>

>>> list_a = [1, 2, 9]
>>> list_b = [1, 3, 9]
>>> all([x % 2 for x in list_a])
False
>>> all([x % 2 for x in list_b])
True

any undall können einen Großteil des gleichen Bereichs abdecken, in dem C ++ - Entwickler nachstd::find oderstd::find_if suchen würden.

Note: In den obigen Beispielenany undall können Sie die Klammern ([]) ohne Funktionsverlust entfernen. (Beispiel:all(x % 2 for x in list_a)) Hierbei werdengenerator expressions verwendet, die zwar recht praktisch sind, jedoch den Rahmen dieses Artikels sprengen.

Bevor Sie mit der Variablentypisierung fortfahren, aktualisieren Sie Ihre Vergleichstabelle zwischen Python und C ++:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Single-Type-Variablen

x

Variablen mit mehreren Typen

x

Verständnis

x

Umfangreiche integrierte Algorithmen

x

x

Okay, jetzt können Sie sich mit der Eingabe von Variablen und Parametern befassen. Lass uns gehen!

Statische und dynamische Typisierung

Ein weiteres großes Thema beim Vergleich von Python mit C ist die Verwendung von Datentypen. C ist eine statisch typisierte Sprache, während Python dynamisch typisiert ist. Lassen Sie uns untersuchen, was das bedeutet.

Statische Typisierung

C ++ ist statisch typisiert. Dies bedeutet, dass jede Variable, die Sie in Ihrem Code verwenden, einen bestimmten Datentyp wieint,char,float usw. haben muss. Sie können einer Variablen nur Werte des richtigen Typs zuweisen, es sei denn, Sie springen durch einige Rahmen.

Dies hat sowohl für den Entwickler als auch für den Compiler einige Vorteile. Der Entwickler hat den Vorteil, dass er im Voraus weiß, welcher Typ einer bestimmten Variablen vorliegt und welche Operationen zulässig sind. Der Compiler kann die Typinformationen verwenden, um den Code zu optimieren und ihn kleiner, schneller oder beides zu machen.

Dieses Vorwissen ist jedoch mit Kosten verbunden. Die an eine Funktion übergebenen Parameter müssen mit dem von der Funktion erwarteten Typ übereinstimmen, was die Flexibilität und den potenziellen Nutzen des Codes verringern kann.

Ententippen

Dynamische Eingabe wird häufig alsduck typing.bezeichnet. Es ist ein seltsamer Name, und Sie werden in nur einer Minute mehr darüber lesen! Beginnen wir jedoch zunächst mit einem Beispiel. Diese Funktion nimmt ein Dateiobjekt und liest die ersten zehn Zeilen:

def read_ten(file_like_object):
    for line_number in range(10):
        x = file_like_object.readline()
        print(f"{line_number} = {x.strip()}")

Um diese Funktion zu verwenden, erstellen Sie ein Dateiobjekt und übergeben es:

with open("types.py") as f:
    read_ten(f)

Dies zeigt, wie das grundlegende Design der Funktion funktioniert. Während diese Funktion als "Lesen der ersten zehn Zeilen aus einem Dateiobjekt" beschrieben wurde, gibt es in Python nichts, was erfordert, dassfile_like_objectbeeine Datei ist. Solange das übergebene Objekt.readline() unterstützt, kann das Objekt von einem beliebigen Typ sein:

class Duck():
    def readline(self):
        return "quack"

my_duck = Duck()
read_ten(my_duck)

Das Aufrufen vonread_ten() mit einemDuck-Objekt erzeugt:

0 = quack
1 = quack
2 = quack
3 = quack
4 = quack
5 = quack
6 = quack
7 = quack
8 = quack
9 = quack

Dies ist die Essenz vonduck typing. Das Sprichwort lautet: "Wenn es wie eine Ente aussieht, wie eine Ente schwimmt und wie eine Ente quakt, dann ist es wahrscheinlichiseine Ente."

Mit anderen Worten, wenn das Objekt über die erforderlichen Methoden verfügt, ist es akzeptabel, es unabhängig vom Objekttyp weiterzugeben. Ente oder dynamisches Tippen bieten Ihnen eine enorme Flexibilität, da jeder Typ dort verwendet werden kann, wo er die erforderlichen Schnittstellen erfüllt.

Hier gibt es jedoch ein Problem. Was passiert, wenn Sie ein Objekt übergeben, dessendoesn’tdie erforderliche Schnittstelle erfüllt? Was ist zum Beispiel, wenn Sie eine Zahl anread_ten() übergeben, wie folgt:read_ten(3)?

Dies führt dazu, dass eine Ausnahme ausgelöst wird. Wenn Sie die Ausnahme nicht abfangen, wird Ihr Programm mit einemtraceback in die Luft gesprengt:

Traceback (most recent call last):
  File "", line 1, in 
  File "duck_test.py", line 4, in read_ten
    x = file_like_object.readline()
AttributeError: 'int' object has no attribute 'readline'

Dynamisches Tippen kann ein ziemlich mächtiges Werkzeug sein, aber wie Sie sehen können, müssen Sie bei der Verwendung Vorsicht walten lassen.

Note: Python und C gelten beide als https://stackoverflow.com/a/11328980[ stark typisierte] Sprachen. Obwohl C ein stärkeres Typsystem hat, sind die Details für jemanden, der Python lernt, im Allgemeinen nicht von Bedeutung.

Kommen wir zu einer Funktion, die von der dynamischen Typisierung von Python profitiert: Vorlagen.

Vorlagen

Python verfügt nicht über Vorlagen wie C ++, benötigt diese jedoch im Allgemeinen nicht. In Python ist alles eine Unterklasse eines einzelnen Basistyps. Auf diese Weise können Sie Enten-Tippfunktionen wie die oben genannten erstellen.

Mit dem Template-System in C ++ können Sie Funktionen oder Algorithmen erstellen, die mit mehreren verschiedenen Typen arbeiten. Dies ist sehr leistungsfähig und kann Ihnen viel Zeit und Mühe sparen. Dies kann jedoch auch zu Verwirrung und Frustration führen, da Compilerfehler in Vorlagen Sie verwirren können.

Die Möglichkeit, Enten anstelle von Vorlagen zu verwenden, erleichtert einige Dinge erheblich. Aber auch dies kann zu schwer zu erkennenden Problemen führen. Wie bei allen komplexen Entscheidungen gibt es Kompromisse beim Vergleich von Python mit C ++.

Typprüfung

In letzter Zeit gab es in der Python-Community großes Interesse und Diskussionen über die statische Typprüfung in Python. Projekte wiemypy haben die Möglichkeit eröffnet, bestimmten Stellen in der Sprache eine Typprüfung vor der Laufzeit hinzuzufügen. Dies kann bei der Verwaltung von Schnittstellen zwischen Teilen großer Pakete oder bestimmten APIs sehr nützlich sein.

Es hilft, einen der Nachteile der Ententypisierung anzugehen. Für Entwickler, die eine Funktion verwenden, ist es hilfreich, wenn sie vollständig verstehen können, was jeder Parameter sein muss. Dies kann in großen Projektteams nützlich sein, in denen viele Entwickler über APIs kommunizieren müssen.

Schauen wir uns noch einmal Ihre Vergleichstabelle Python vs C ++ an:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Single-Type-Variablen

x

Variablen mit mehreren Typen

x

Verständnis

x

Umfangreiche integrierte Algorithmen

x

x

Statische Typisierung

x

Dynamische Eingabe

x

Jetzt können Sie sich den Unterschieden in der objektorientierten Programmierung zuwenden.

Objekt orientierte Programmierung

Wie C unterstützt Python ein https://realpython.com/courses/intro-object-oriented-programming-oop-python/[object-oriented Programmiermodell]. Viele der Konzepte, die Sie in C gelernt haben, werden in Python übertragen. Sie müssen noch Entscheidungen überinheritance, composition und Mehrfachvererbung treffen.

Ähnlichkeiten

Inheritance zwischen Klassen funktioniert in Python und C ähnlich. Eine neue Klasse kann Methoden und Attribute von einer oder mehreren Basisklassen erben, genau wie Sie es in C gesehen haben. Einige Details sind jedoch etwas anders.

Bei Basisklassen in Python wird der Konstruktor nicht wie in C ++ automatisch aufgerufen. Dies kann verwirrend sein, wenn Sie die Sprache wechseln.

Multiple inheritance funktioniert auch in Python und hat genauso viele Macken und seltsame Regeln wie in C ++.

In ähnlicher Weise können Sie auch Komposition verwenden, um Klassen zu erstellen, in denen Objekte eines Typs andere Typen enthalten. Wenn man bedenkt, dass in Python alles ein Objekt ist, bedeutet dies, dass Klassen alles andere in der Sprache enthalten können.

Unterschiede

Es gibt jedoch einige Unterschiede, wenn Sie Python mit C ++ vergleichen. Die ersten beiden sind verwandt.

Der erste Unterschied besteht darin, dass Python kein Konzept für Zugriffsmodifikatoren für Klassen hat. Alles in einem Klassenobjekt ist öffentlich. Die Python-Community hat eine Konvention entwickelt, nach der jedes Mitglied einer Klasse, das mit einem einzelnen Unterstrich beginnt, als privat behandelt wird. Dies wird in keiner Weise von der Sprache erzwungen, aber es scheint ziemlich gut zu funktionieren.

Die Tatsache, dass jedes Klassenmitglied und jede Methode in Python öffentlich ist, führt zum zweiten Unterschied: Python bietet eine weitaus schwächere Kapselungsunterstützung als C ++.

Wie bereits erwähnt, ist dies aufgrund der Konvention mit einem einzigen Unterstrich in praktischen Codebasen weitaus weniger ein Problem als im theoretischen Sinne. Im Allgemeinen bittet jeder Benutzer, der gegen diese Regel verstößt und von der internen Arbeitsweise einer Klasse abhängt, um Probleme.

Operatorüberladungen vs Dunder-Methoden

In C + können Sie * Operatorüberladungen * hinzufügen. Mit diesen können Sie das Verhalten bestimmter syntaktischer Operatoren (wie `==`) für bestimmte Datentypen definieren. Normalerweise wird dies verwendet, um Ihre Klassen natürlicher zu nutzen. Für den Operator `== +` können Sie genau definieren, was es bedeutet, dass zwei Objekte einer Klasse gleich sind.

Ein Unterschied, den einige Entwickler lange brauchen, um zu verstehen, wie man das Fehlen von Operatorüberladungen in Python umgeht. Es ist großartig, dass alle Python-Objekte in einem der Standardcontainer funktionieren. Was ist jedoch, wenn der Operator==einen umfassenden Vergleich zwischen zwei Objekten Ihrer neuen Klasse durchführen soll? In C + würden Sie in Ihrer Klasse einen `+ Operator == ()` erstellen und den Vergleich durchführen.

Python hat eine ähnliche Struktur, die in der gesamten Sprache ziemlich konsistent verwendet wird:dunder methods. Dunder-Methoden erhalten ihren Namen, weil sie alle mit einem doppelten Unterstrich oder „d-under“ beginnen und enden.

Viele der integrierten Funktionen, die für Objekte in Python ausgeführt werden, werden durch Aufrufe derdunder methods dieses Objekts ausgeführt. In Ihrem obigen Beispiel können Sie Ihrer Klasse__eq__() hinzufügen, um einen beliebigen Vergleich durchzuführen:

class MyFancyComparisonClass():
    def __eq__(self, other):
        return True

Dies erzeugt eine Klasse, die auf die gleiche Weise wie jede andere Instanz ihrer Klasse verglichen wird. Nicht besonders nützlich, aber es zeigt den Punkt.

In Python wird eine große Anzahl von Dunder-Methoden verwendet, und die integrierten Funktionen nutzen sie in großem Umfang. Wenn Sie beispielsweise__lt__() hinzufügen, kann Python die relative Reihenfolge von zwei Ihrer Objekte vergleichen. Dies bedeutet, dass jetzt nicht nur der Operator< funktioniert, sondern auch>,<= und>=.

Noch besser ist, wenn Sie mehrere Objekte Ihrer neuen Klasse in einer Liste haben, können Siesorted() in der Liste verwenden und sie werden mit__lt__() sortiert.

Schauen wir uns noch einmal Ihre Vergleichstabelle Python vs C ++ an:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Single-Type-Variablen

x

Variablen mit mehreren Typen

x

Verständnis

x

Umfangreiche integrierte Algorithmen

x

x

Statische Typisierung

x

Dynamische Eingabe

x

Strikte Verkapselung

x

Nachdem Sie nun die objektorientierte Codierung in beiden Sprachen gesehen haben, schauen wir uns an, wie Python und C ++ diese Objekte im Speicher verwalten.

Speicherverwaltung

Einer der größten Unterschiede beim Vergleich von Python mit C ist der Umgang mit dem Speicher. Wie Sie im Abschnitt über Variablen in C- und Python-Namen gesehen haben, verfügt Python weder über Zeiger noch lässt es Sie einfach, den Speicher direkt zu manipulieren. Es gibt Zeiten, in denen Sie diese Kontrolle haben möchten, aber meistens ist dies nicht erforderlich.

Das Aufgeben der direkten Kontrolle über Speicherorte bringt einige Vorteile. Sie müssen sich keine Gedanken über den Speicherbesitz machen oder sicherstellen, dass der Speicher nach der Zuweisung einmal (und nur einmal) freigegeben wird. Sie müssen sich auch nie darum kümmern, ob ein Objekt auf dem Stapel oder auf dem Heap zugewiesen wurde oder nicht, was dazu führt, dass beginnende C ++ - Entwickler stolpern.

Python verwaltet all diese Probleme für Sie. Um dies zu tun, ist alles in Python eine abgeleitete Klasse von Pythonsobject. Auf diese Weise kann der Python-Interpreter die Referenzzählung implementieren, um zu verfolgen, welche Objekte noch verwendet werden und welche freigegeben werden können.

Diese Bequemlichkeit hat natürlich ihren Preis. Um zugewiesene Speicherobjekte für Sie freizugeben, muss Python gelegentlich so genanntegarbage collector ausführen, die nicht verwendete Speicherobjekte finden und freigeben.

Note: CPython hat ein komplexesmemory management scheme, was bedeutet, dass das Freigeben von Speicher nicht unbedingt bedeutet, dass der Speicher an das Betriebssystem zurückgegeben wird.

Python verwendet zwei Tools, um Speicher freizugeben:

  1. Der Referenzzählsammler

  2. Der Generationssammler

Schauen wir uns diese einzeln an.

Referenzzählungskollektor

Der Referenzzählungskollektor ist für den Standard-Python-Interpreter von grundlegender Bedeutung und wird immer ausgeführt. Dabei wird nachverfolgt, wie oft einem bestimmten Speicherblock (der immer ein Pythonobject ist) ein Name zugeordnet ist, während Ihr Programm ausgeführt wird. Viele Regeln beschreiben, wann der Referenzzähler inkrementiert oder dekrementiert wird, aber ein Beispiel für einen Fall könnte Folgendes verdeutlichen:

>>>

 1 >>> x = 'A long string'
 2 >>> y = x
 3 >>> del x
 4 >>> del y

Im obigen Beispiel erstellt Zeile 1 ein neues Objekt, das die Zeichenfolge"A long string" enthält. Anschließend wird der Namex auf dieses Objekt gesetzt, wodurch die Referenzanzahl des Objekts auf 1 erhöht wird:

A Python object with reference count of one.

In Zeile 2 wirdy zugewiesen, um dasselbe Objekt zu benennen, wodurch die Referenzanzahl auf 2 erhöht wird:

A Python object with reference count of two.

Wenn Siedel mitx in Zeile 3 aufrufen, entfernen Sie einen der Verweise auf das Objekt und setzen die Anzahl auf 1 zurück:

Two Python objects

Wenn Sie schließlichy, die endgültige Referenz auf das Objekt, entfernen, sinkt die Referenzanzahl auf Null und kann vom Garbage Collector für die Referenzzählung freigegeben werden. Es kann zu diesem Zeitpunkt sofort freigegeben werden oder nicht, aber im Allgemeinen sollte dies für den Entwickler keine Rolle spielen:

The Python None object with reference count of two and another Python object with reference count of zero.

Während dies dafür sorgt, dass viele der Objekte, die befreit werden müssen, gefunden und freigegeben werden, gibt es einige Situationen, die nicht erfasst werden. Dafür benötigen Sie den Garbage Collector der Generation.

Generationsmüllsammler

Eine der großen Lücken im Referenzzählschema besteht darin, dass Ihr Programm einen Referenzzyklus erstellen kann, in dem ObjektA auf ObjektB verweist, das auf ObjektAverweist. s. Es ist durchaus möglich, diese Situation zu treffen und nichts in Ihrem Code zu haben, das sich auf eines der Objekte bezieht. In diesem Fall erreicht keines der Objekte jemals einen Referenzzähler von 0.

Dasgenerational garbage collector beinhaltet einen komplexen Algorithmus, der den Rahmen dieses Artikels sprengt, aber einige dieser verwaisten Referenzzyklen findet und für Sie freigibt. Es wird gelegentlich ausgeführt und durch die beschriebenen Einstellungenin the documentation gesteuert. Einer dieser Parameter besteht darin, diesen Garbage Collector vollständig zu deaktivieren.

Wenn Sie keine Müllabfuhr wünschen

Wenn Sie Python mit C vergleichen, wie wenn Sie zwei beliebige Tools vergleichen, ist jeder Vorteil mit einem Kompromiss verbunden. Python erfordert keine explizite Speicherverwaltung, verbringt jedoch gelegentlich mehr Zeit als erwartet mit der Speicherbereinigung. Das Umgekehrte gilt für C: Ihr Programm hat konsistente Antwortzeiten, aber Sie müssen mehr Aufwand für die Speicherverwaltung aufwenden.

In vielen Programmen ist der gelegentliche Treffer bei der Speicherbereinigung unwichtig. Wenn Sie ein Skript schreiben, das nur 10 Sekunden lang ausgeführt wird, ist es unwahrscheinlich, dass Sie den Unterschied bemerken. Einige Situationen erfordern jedoch konsistente Antwortzeiten. Echtzeitsysteme sind ein gutes Beispiel, bei dem das Reagieren auf eine Hardware in einer festgelegten Zeitspanne für den ordnungsgemäßen Betrieb Ihres Systems von entscheidender Bedeutung sein kann.

Systeme mit hohen Echtzeitanforderungen sind einige der Systeme, für die Python eine schlechte Sprachwahl ist. Ein streng kontrolliertes System, bei dem Sie sich über das Timing sicher sind, ist eine gute Verwendung von C ++. Dies sind die Arten von Problemen, die Sie berücksichtigen müssen, wenn Sie sich für die Sprache eines Projekts entscheiden.

Zeit, Ihr Python vs C ++ - Diagramm zu aktualisieren:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Single-Type-Variablen

x

Variablen mit mehreren Typen

x

Verständnis

x

Umfangreiche integrierte Algorithmen

x

x

Statische Typisierung

x

Dynamische Eingabe

x

Strikte Verkapselung

x

Direkte Speichersteuerung

x

Speicherbereinigung

x

Threading, Multiprocessing und Async IO

Die Parallelitätsmodelle in C ++ und Python sind ähnlich, haben jedoch unterschiedliche Ergebnisse und Vorteile. Beide Sprachen unterstützen Threading-, Multiprocessing- und Async-E / A-Vorgänge. Schauen wir uns diese an.

Einfädeln

Während sowohl C als auch Python Threading in die Sprache integriert haben, können die Ergebnisse je nach dem Problem, das Sie lösen, deutlich unterschiedlich sein. Häufig wird https://realpython.com/intro-to-python-threading/[threading] verwendet, um Leistungsprobleme zu beheben. In C kann das Threading eine allgemeine Beschleunigung sowohl für rechnerisch gebundene als auch für E / A-gebundene Probleme bieten, da Threads die Kerne eines Multiprozessorsystems voll ausnutzen können.

Python hat andererseits einen Design-Kompromiss geschlossen, umGlobal Interpreter Lock oderGIL zu verwenden, um die Threading-Implementierung zu vereinfachen. Die GIL bietet viele Vorteile, aber der Nachteil ist, dass immer nur ein Thread gleichzeitig ausgeführt wird, selbst wenn mehrere Kerne vorhanden sind.

Wenn Ihr Problem an die E / A gebunden ist, z. B. das gleichzeitige Abrufen mehrerer Webseiten, stört Sie diese Einschränkung nicht im geringsten. Sie werden das einfachere Threading-Modell und die integrierten Methoden von Python fürinter-thread communications zu schätzen wissen. Wenn Ihr Problem jedoch an die CPU gebunden ist, beschränkt die GIL Ihre Leistung auf die eines einzelnen Prozessors. Glücklicherweise hat die Multiprocessing-Bibliothek von Python eine ähnliche Oberfläche wie die Threading-Bibliothek.

Mehrfachverarbeitung

Die Unterstützung vonMultiprocessingin Python ist in die Standardbibliothek integriert. Es verfügt über eine übersichtliche Oberfläche, über die Sie mehrere Prozesse starten und Informationen zwischen ihnen austauschen können. Sie können einen Pool von Prozessen erstellen und die Arbeit mit verschiedenen Techniken auf diese verteilen.

Während Python zum Erstellen der neuen Prozesse immer noch ähnliche Betriebssystemprimitive verwendet, ist ein Großteil der Komplikationen auf niedriger Ebene dem Entwickler verborgen.

C ++ verwendetfork(), um Multiprozessor-Unterstützung bereitzustellen. Auf diese Weise haben Sie direkten Zugriff auf alle Steuerelemente und Probleme beim Laichen mehrerer Prozesse. Dies ist jedoch auch viel komplexer.

Async IO

Sowohl Python als auch C unterstützen Async IO-Routinen, werden jedoch unterschiedlich behandelt. In C verwenden diestd::async-Methoden wahrscheinlich Threading, um die asynchrone E / A-Natur ihrer Operationen zu erreichen. In Python wird der Code vonAsync IOnur auf einem einzelnen Thread ausgeführt.

Auch hier gibt es Kompromisse. Durch die Verwendung separater Threads kann der C ++ Async IO-Code bei rechnerisch gebundenen Problemen schneller ausgeführt werden. Die Python-Tasks, die in der Async IO-Implementierung verwendet werden, sind leichter, sodass es schneller ist, eine große Anzahl von Tasks zu starten, um E / A-gebundene Probleme zu lösen.

Ihre Python vs C ++ - Vergleichstabelle bleibt für diesen Abschnitt unverändert. Beide Sprachen unterstützen eine Vielzahl von Parallelitätsoptionen mit unterschiedlichen Kompromissen zwischen Geschwindigkeit und Komfort.

Verschiedene Probleme

Wenn Sie Python mit C ++ vergleichen und Python zu Ihrem Toolbelt hinzufügen möchten, sollten Sie noch einige andere Aspekte berücksichtigen. Während Ihr aktueller Editor oder Ihre IDE sicherlich für Python funktioniert, möchten Sie möglicherweise bestimmte Erweiterungen oder Sprachpakete hinzufügen. Es lohnt sich auch,PyCharmeinen Blick darauf zu werfen, da es Python-spezifisch ist.

Einige C ++ - Projekte haben Python-Bindungen. Dinge wieQt,WxWidgets und viele Messaging-APIs mit mehrsprachigen Bindungen.

Wenn Sieembed Python in C++ möchten, können SiePython/C API verwenden.

Schließlich gibt es verschiedene Methoden, um mithilfe Ihrer C-Kenntnisse Python zu erweitern und Funktionen hinzuzufügen oder um Ihre vorhandenen C-Bibliotheken aus Ihrem Python-Code heraus aufzurufen. Mithilfe von Tools wieCTypes,Cython,CFFI,Boost.Python undSwig können Sie diese Sprachen kombinieren und für das Beste verwenden.

Zusammenfassung: Python vs C ++

Sie haben einige Zeit damit verbracht, die Unterschiede zwischen Python und C ++ zu lesen und darüber nachzudenken. Python hat zwar eine einfachere Syntax und weniger scharfe Kanten, ist jedoch nicht für alle Probleme geeignet. Sie haben sich mit der Syntax, der Speicherverwaltung, der Verarbeitung und verschiedenen anderen Aspekten dieser beiden Sprachen befasst.

Werfen wir einen letzten Blick auf Ihre Vergleichstabelle zwischen Python und C ++:

Feature Python C++

Schnellere Ausführung

x

Plattformübergreifende Ausführung

x

Single-Type-Variablen

x

Variablen mit mehreren Typen

x

Verständnis

x

Umfangreiche integrierte Algorithmen

x

x

Statische Typisierung

x

Dynamische Eingabe

x

Strikte Verkapselung

x

Direkte Speichersteuerung

x

Speicherbereinigung

x

Wenn Sie Python mit C ++ vergleichen, können Sie Ihrem Diagramm entnehmen, dass dies kein Fall ist, in dem einer besser ist als der andere. Jedes von ihnen ist ein Werkzeug, das für verschiedene Anwendungsfälle gut entwickelt wurde. So wie Sie keinen Hammer zum Einschlagen von Schrauben verwenden, erleichtert die Verwendung der richtigen Sprache für den Job Ihr Leben!

Fazit

Glückwunsch! Sie haben jetzt einige der Stärken und Schwächen von Python und C ++ gesehen. Sie haben einige der Funktionen der einzelnen Sprachen und deren Ähnlichkeit kennengelernt.

Sie haben gesehen, dass C ++ großartig ist, wenn Sie möchten:

  • Schnelle Ausführungsgeschwindigkeit (möglicherweise auf Kosten der Entwicklungsgeschwindigkeit)

  • Vollständige Kontrolle über das Gedächtnis

Umgekehrt ist Python großartig, wenn Sie möchten:

  • Schnelle Entwicklungsgeschwindigkeit (möglicherweise auf Kosten der Ausführungsgeschwindigkeit)

  • Verwalteter Speicher

Sie sind jetzt bereit, eine kluge Sprachwahl zu treffen, wenn es um Ihr nächstes Projekt geht!