Equivalents were produced with the Free Edition of C++ to Python Converter.
Sized Array
C++ | Python |
---|---|
int myArray[2]; or: int *myArray = new int[2]; |
myArray = [0 for _ in range(2)] |
Access Array Element
C++ | Python |
---|---|
x = myArray[0]; | x = myArray[0] |
Array of Arrays
C++ | Python |
---|---|
int myArray[2][3] = { {1,2,3}, {4,5,6} }; | myArray = [[1, 2, 3], [4, 5, 6]] |
C++ requires statements to end with semi-colons and multi-statement blocks to be enclosed in braces, while Python only requires indentation to correspond to the logical block levels and block headers to end in colons. The current instance is only available within instance methods via the first parameter of the method, usually named 'self' by convention (static methods are distinguished by the @staticmethod decorator).
C++ | Python |
---|---|
class FooClass { void instanceMethod() { if (fooCondition) { fooLogicOne(); fooLogicTwo(); } } }; |
class FooClass: def instanceMethod(self): if fooCondition: fooLogicOne() fooLogicTwo() |
C++ | Python |
---|---|
void casts() { x = (int)y; x = (float)y; x = (std::string)y; } |
def casts(self): x = int(y) x = float(y) x = str(y) |
C++ | Python |
---|---|
// vector: std::vector<int> myList = {1, 2, 3}; // unordered_map: std::unordered_map<std::wstring, int> myD = { {string1, 80}, {string2, 85} }; |
# list: myList = [1, 2, 3] # dict: myD = {string1: 80, string2: 85} |
Vectors (C++) and lists (Python)
C++ | Python |
---|---|
#include <vector> void Vector() { std::vector<int> myList; myList.push_back(1); int i = 1; myList[0] = i; i = myList[0]; } |
def list(self): myList = [] myList.append(1) i = 1 myList[0] = i i = myList[0] |
Maps (C++) and dictionaries (Python)
C++ | Python |
---|---|
#include <string> #include <unordered_map> void UnorderedMap() { std::unordered_map<std::wstring, int> map; std::wstring s = L"test"; map.emplace(s, 1); int i = map[s]; i = map.size(); bool b = map.empty(); map.erase(s); } |
def dictionary(self): map = {} s = "test" map.update({s: 1}) i = map[s] i = len(map) b = not map map.pop(s) |
Python has a single comment format, starting with the '#' symbol. Multiline comments can also be created using triple quoted multiline strings.
C++ | Python |
---|---|
// single-line comment foo(); // end-of-line comment /* comment over multiple lines */ |
# single-line comment foo() # end-of-line comment # comment # over multiple lines # # using multiline strings to simulate multiline comments: """ comment over multiple lines """ |
Local Variable
C++ | Python |
---|---|
int myVar = 2; | myVar = 2 # Python infers the type |
Inferred Types
Inferred typing is available in C++, but Python always infers the type:
C++ | Python |
---|---|
auto myVar = 2; | myVar = 2 |
Static Field
In Python, static fields are initialized at the class level:
C++ | Python |
---|---|
class FooClass { static inline int staticField = 7; }; |
class FooClass: staticField = 7 |
Instance Field
In Python, instance fields are not listed at the class level and are qualified with the instance object, given by the first instance method parameter (usually named 'self' by convention):
C++ | Python |
---|---|
class FooClass { int instanceField = 2; }; |
class FooClass: def __init__(self): self.instanceField = 2 |
Local Constant
C++ | Python |
---|---|
constexpr int myConst = 2; | MY_CONST = 2 # at method level — up to programmers to respect the naming convention and avoid changing it |
Class Constant
C++ | Python |
---|---|
static constexpr int myConst = 2; | MY_CONST = 2 # at class level — up to programmers to respect the naming convention and avoid changing it |
C++ | Python |
---|---|
class Foo { public: Foo() // constructor { } ~Foo() // destructor { } }; |
class Foo: def __init__(self): # constructor pass def close(self): # destructor pass |
The syntax for default parameters is identical in these two languages.
C++ | Python |
---|---|
void defaultParam(int x=0) { ... } |
def defaultParam(self, x=0): ... |
Enums in C++ have equivalents in Python using the 'enum' module:
C++ | Python |
---|---|
enum class Simple { FOO, BAR }; |
from enum import Enum class Simple(Enum): FOO = 0 BAR = 1 |
The Python try/except scheme is equivalent to the C++ try/catch:
C++ | Python |
---|---|
void ExceptionHandling() { try { } catch (const Foo &f) { throw Foo(); } catch (const Bar) { throw Bar(); } catch (...) { throw FooBar(); } } |
def ExceptionHandling(self): try: pass except Foo as f: raise Foo() except Bar: raise Bar() except: raise FooBar() |
C++ | Python |
---|---|
if (conditionA) { } else if (conditionB) { } else { } |
if conditionA: pass elif conditionB: pass else: pass |
C++ allows incrementing and decrementing integers within expressions, while Python doesn't. The following shows how C++ to Python Converter handles some cases.
C++ | Python |
---|---|
void incrementDecrement() { i = ++j; i = j++; i = j--; i = s + --t; i = s + t--; i = s + ++t; i = s + t++; } |
def incrementDecrement(self): j += 1 i = j i = j j += 1 i = j j -= 1 t -= 1 i = s + t i = s + t t -= 1 t += 1 i = s + t i = s + t t += 1 |
Python does not have indexers, so you must use get/set methods instead:
C++ | Python |
---|---|
public: int &operator [](int index) { return field[index]; } |
def get_item(self, index): return field[index] def set_item(self, index, value): field[index] = value |
C++ | Python |
---|---|
class one { protected: int baseField = 1; public: one(int i) { } virtual void baseMethod() { } }; class two : public one { public: two() : one(0) { } void method() { one::baseField = 2; one::baseMethod(); } }; |
class one: def __init__(self, i): # instance fields found by C++ to Python Converter: self.baseField = 1 def baseMethod(self): pass class two(one): def __init__(self): super().__init__(0) def method(self): self.baseField = 2 super().baseMethod() |
Expression Lambda
C++ | Python |
---|---|
myVar = [&] (const std::string &text) { return foo(text); }; |
myVar = lambda text : foo(text) |
Multi-statement Lambda
C++ | Python |
---|---|
myVar = [&] (Foo *param1, Bar *param2) { // ...multiple statements }; |
No direct Python equivalent |
C++ | Python |
---|---|
x = y && z; x = y || z; x = !y; i = j | k; i = j & k; i = j ^ k; |
x = y and z x = y or z x = not y i = j | k i = j & k i = j ^ k |
C++ | Python |
---|---|
// while loop: while (while_condition) { foo(); // break and continue: if (b) break; else continue; } // do-while loop: do { foo(); } while (do_condition); // traditional for loop: for (int i = 0; i < 10; i++) { foo(); } // 'for each' loop: for (Foo f : FooList) { } |
# while loop: while while_condition: foo() # break and continue: if b: break else: continue # do-while loop: # Python doesn't have a do-while loop, so simulate it: condition = True while condition: foo() condition = do_condition # traditional for loop: for i in range(0, 9): foo() # 'for each' loop: for f in FooList: pass |
C++ | Python |
---|---|
void exponentiation() { x = std::pow(y, z); } void integerDivision() { // C++ integer division always rounds towards 0: int i = -5; int j = 2; int result = i / j; // result is -2 } void modulusOperator() { // C++ and Python '%' operators are only equivalent for positive numbers: int i = 2; int j = -3; int result = i % j; // result is 2 } void otherMathOperations() { x = std::abs(y); x = std::cos(y); x = M_E; x = M_PI; } |
import math def exponentiation(self): x = y ** z def integerDivision(self): # Python integer division rounds away from 0 when negative: i = -5 j = 2 result = math.trunc(i / float(j)) # result is -2 def modulusOperator(self): i = 2 j = -3 result = math.fmod(i, j) # result is 2 # Python modulus operator produces a different result: result = i % j # result is -1 def otherMathOperations(self): x = abs(y) x = math.cos(y) x = math.e x = math.pi |
Python instance methods have a first parameter indicating the instance ('self' is the convention for this parameter and not a keyword), and static methods have the '@staticmethod' decorator.
C++ | Python |
---|---|
void instanceMethod() { } static void staticMethod() { } |
def instanceMethod(self): pass @staticmethod def staticMethod(): pass |
C++ to Python Converter uses classes to simulate namespaces:
C++ | Python |
---|---|
namespace foo_namespace { class FooClass { }; } |
class foo_namespace: class FooClass: pass |
Python doesn't offer operator overloading, so you have to create instance methods in the place of operator overloads:
C++ | Python |
---|---|
class SomeType { private: int intValue = 0; public: int operator + (const SomeType &Y) { return this->intValue + Y.intValue; } void test() { SomeType o1, o2; int i = o1 + o2; } }; |
class SomeType:
def __init__(self): # instance fields found by C++ to Python Converter: self._intValue = 0 def add(self, Y): return self._intValue + Y._intValue def test(self): o1 = SomeType() o2 = SomeType() i = o1.add(o2) |
The closest thing in Python to a C++ pure virtual method is an empty method:
C++ | Python |
---|---|
class AbstractClass { protected: virtual void abstractMethod() = 0; }; |
class AbstractClass: def abstractMethod(self): pass |
C++ | Python |
---|---|
std::string s = R"(multiline raw string)"; |
s = """multiline raw string""" |
Python 3.10 has 'match' syntax, but if/elif/else is used prior to Python 3.10.
C++ | Python |
---|---|
switch (pivot) { case 1: foo(); break; case 2: case 3: bar(); break; case 4: break; default: ack(); break; } |
Python 3.10: match pivot: case 1: foo() case 2 | 3: bar() case 4: pass case other: ack() Prior to Python 3.10: if pivot == 1: foo() elif pivot == 2 or pivot == 3: bar() elif pivot == 4: pass else: ack() |
C++ | Python |
---|---|
result = condition ? truePart : falsePart; | result = truePart if condition else falsePart |
There is no direct equivalent in C++ to the Python 'isinstance' operator, but you can replicate the behavior by testing the result of a 'dynamic_cast':
C++ | Python |
---|---|
bool b = dynamic_cast<Foo*>(f) != nullptr; | b = isinstance(f, Foo) |
Copyright © 2004 – 2024 Tangible Software Solutions, Inc.