Python和C++都是面向对象的。
Python和C++的区别:
- Python是脚本语言,脚本语言不需要编译,直接解释执行,由解释器来负责解释。程序代码即是脚本程序,也是可执行文件,只需要编写-运行。
- C++是编译型编程语言,需要编译成二进制代码,以可执行文件形式运行,需要经过编写-编译-链接-运行的过程。
从语法角度来说:Python更加灵活;C++逻辑更加清晰。
Python | C++ | |
import cmath 导入模块,每一个.py文件都可以认为是一个模块。Python中导入的模块可以是类的定义,函数的定义。 |
#include<cmath> 引入头文件,头文件为类或函数的声明。 C++支持分离式编译,对源文件分别编译成目标文件,再链接生成可执行文件。通过头文件把源文件关联起来。 |
|
在python程序中直接添加sys.path,即import时寻找模块的路径 | 在cmakelist中设置include_directories(),即include时寻找相应头文件的路径 |
|
在程序中添加单元测试 | if __name__ == "__main__":
扫描二维码关注公众号,回复:
13113759 查看本文章
![]() 当模块被作为脚本直接运行时,执行之后的程序块; 当模块被其他模块导入时,不执行之后的程序块。 非常方便,可以直接将单元测试脚本写在if __name__ == "__main__":后,保证程序功能正常 |
C++需要有一个 main 函数来作为程序的入口。如果需要单元测试需要单独写带有main函数的源文件。 |
类的构造函数和析构函数 | class Foobar: def __init__(self):
def __del__(self): 使用魔法(特殊)方法机制,魔法方法是以__开头和__结尾的方法,在特定情况下自动被Python调用,而无需手动直接调用 |
class Foobar{ Foobar(){}; ~Foobar(){}; }; 和类同名的函数,无返回类型, |
方法和数据成员绑定到对象 | self 类定义中成员函数的第一个参数必须显式为self; 对象调用成员函数时不用传入该参数,python解释器会自己把实例变量传进去。 |
this 常量指针,指向对象地址 类的成员函数通过this的隐式形参访问调用它的对象。类中定义成员函数时和对象调用成员函数时都不用显式传入this。 在成员函数中return *this返回的正是调用该函数的对象 |
数据成员 | python中称为对象的数据成员 在类的构造函数内直接定义: class Example: def __init__(self): self.mymember=1 也可以在对象中直接添加或删除对象的数据成员: example=Example() example.mysecondmember=2. del example.mymember 这充分体现了Python的灵活性。 |
在类的方法外声明数据成员,随后对类实例化,每一个对象拥有数据成员;在对象中无法再添加或删除数据成员 class Example{ Example(int x):member(x){}; int mymember; }; Example example; C++的数据成员一目了然,非常清晰。 |
类的静态成员 | python中称为类的数据成员 class Example: classmember=4 在类中但不在类的方法中定义的数据成员为类的数据成员,所有类的实例化对象共享类的数据成员,在类内或类外可以通过Example.classmember获取类的数据成员 |
class Example{ static init mymember; }; int x; x=Example::mymember; |
类方法 | class Example: classmember=4 @classmethod def getclassmember(cls): return cls.classmember |
|
静态成员函数 (类的静态成员函数不与任何对象绑定在一起,不包含this指针) |
class Example: @staticmethod def initsample(): pass 直接调用:Example.initsample() 也可实例化后调用: example=Example() example.initsample() |
class Example{ static double initsample(); }; 直接调用: double r; r=Example::initsample(); 也可实例化后调用: Example example; example.initsample(); |
子类的构造函数初始化父类 | class Fathertarget def __init__(self, class Target( def __init__(self, P1, P2): super().__init__(P1 = |
在子类的构造函数初始化列表中调用父类的构造函数初始化 |
抽象基类 (作为接口) |
class Example: @abstractmethod def examplemethod(self): pass |
class Example{ void examplemethod()=0; }; |
多态 | 对象遵守特定的协议,协议指定需要实现哪些方法以及这些方法应做什么。不基于类的继承关系。 |
基类的指针或引用可以绑定在继承类的对象上,基于此机制实现多态。 |
迭代器 | 实现了方法__iter__的对象是可迭代的,实现了方法__next__的对象是迭代器 | X |
生成器 | 生成器是包含yield语句的函数,是使用普通函数语法定义的迭代器。当生成器被调用时不会执行函数体内的代码,而是返回一个迭代器。每次请求值时都执行生成器的代码,直道遇到yield或return,遇到yield则生成一个值。 | X |
装饰器 | 用于扩展函数功能,在没对函数本身做任何修改的情况下,如其名所示,添加了其它(辅助)功能。 def executetime(func): def wrapper(): time1=time.time() func() time2=time.time() delta_t=time2-time1 print('excecute_time is {}'.format(delta_t)) return wrapper @executetime def myfunc(): time.sleep(5) |
X |
函数内定义函数 (嵌套函数) |
python的函数也是对象,因此可以将函数作为参数传递、可以将函数作为返回、可以将函数放入结构体中(如函数放入数组中)、可以在函数中定义函数; def outer(): x=5 def inner(): y=x+3 #内函数在自己作用域内查找局部变量失败后,会进一步向上一层作用域里查找。 print(y) return inner #闭包:内函数体内引用到外函数中定义的变量,return返回内函数的引用时把内函数和外部引用变量打包成整体返回, 这里inner函数和外部变量x组成闭包 |
不能在函数中定义函数,需要使用函数对象或者匿名函数实现需求 void foo(){ //function object class InnerFunction{ public: void operator()(){ std::cout<<"inner function object"<<std::endl; } }; InnerFunction innerfunction; innerfunction(); //lambda expression auto lambdafunc=[=]()->void{ std::cout<<"inner lambda function"<<end; //lamba表达式需要使用捕获列表才能使用它所在函数中的局部变量 } lambdafunc(); } |
像调用函数一样调用类实例对象 | class Sample: def __call__(self): print("!!!!!") sample=Sample() #实例化 sample() |
使用函数对象,在类中重载()运算符 |
映射(如字典) | 关联容器 | |
Python和C++都有容器的概念:
序列中的每个元素被分配一个序号--即元素的位置,也称为索引。
通用序列操作:索引、分片、序列相加、乘法、成员资格、长度、最小值和最大值。
Python包含6种内建的序列,即列表、元组、字符串、Unicode字符串、buffer对象和 xrange 对象
- 元组 (): 元组的元素不能修改;数据项不需要具有相同的类型
- 列表 []: 相当于C++中的vector容器;数据项不需要具有相同的类型
另外常用的基本内置数据类型包括:
- 集合{ } 或 set() : 无序不重复序列
- 字典 {}
顺序容器操作
Python 序列(sequence ,包括列表、字符串和元组) |
C++ 顺序容器(sequential container,包括vector, deque, list, forward_list, array, string) |
例如:v=['dlsdkf', 60] 无需声明容器的类型以及容器内元素的类型:使用[]表示列表,()表示元组,“”或''表示字符串; 列表中可以放任意类型的元素,甚至在同一列表中可以包含不同类型的元素。 |
C c{a,b}; 例如: std::vector<int> v{2,3,5}; 列表初始化 需要声明容器的类型和容器内元素的类型,容器内元素类型必须相同。 |
索引 v[n], n可为负数,-1表示倒数第一个 |
索引 v[n], n只能为正数 |
切片 v[n:n+m] (左闭右开) v[n:n+m:k] 支持带步长的切片 |
O |
序列相加 v1+v2将两个序列拼接起来 |
O |
乘法 v*5,重复序列v 5次 |
O |
成员资格 60 in v |
O |
len(v) | v.size(); |
min(v) | O |
max(v) | O |
列表
- Python中在每一个容器的方法中定义了大量的操作,例如列表的方法直接实现查询、修改等操作,优点是方便、直观;
- C++在每个容器的方法中只定义了添加、删除等很少的操作,而是以泛型算法的形式实现更多的查找元素、替换或删除特定值、排序等操作,优点是可以用于多种容器类型。泛型算法算法不直接操作容器,通过配合迭代器使用,遍历由两个迭代器指定的一个元素范围来进行操作,使得算法不依赖于容器类型。。
Python 列表的方法 |
C++ 顺序容器(sequential container,包括vector, deque, list, forward_list, array, string) |
计算指定元素出现次数 v.count(60) |
|
列表中查找第一次出现的索引 v.index(60) |
O (可通过泛型算法find实现) |
复制列表 v2=v1.copy() |
|
反序排列 v.reverse() |
O |
排序 v.sort() |
O(可通过泛型算法sort实现) |
末尾添加一个对象 v.append(20) |
v.push_back() |
末尾添加多个对象 v1.extend(v2) |
v.insert() |
将一个对象插入列表 v.insert(2, 69) |
v.insert() |
删除元素 del v[1] |
v.erase() |
删除一个元素 v.pop() v.pop(0) |
v.pop_back() v.pop_front() |
删除第一个为指定值的元素 v.remove(60) |
O |
清空列表 v.clear() |
v.clear() |
备注:O表示无直接命令,需要通过其他方法才能实现。
语法:
Python | C++ | |
if | if condition: statement elif condition: statement else: statement |
if (condition){
} } } |
for循环 | for item in iterable: iterable的可以是列表Occupationt=['teacher','student','driver','governer']、元组(1,2,3)、字典{"name":'Arnold',"Salary":10000}.items()、集合对象{100,‘ab’}、字符串 ‘abcdefg’。 for i in range(0,10): |
for (init-state;condition;expression){
} C++范围for语句实现类似于Python的遍历序列: for (auto item : iterable){
} iterable为一个序列,可以是数组、vector、string, 必须拥有能返回迭代器begin和end的成员。 for (i=0;i<10;i++){
} |
while循环 | while condition: statement |
while (condition){
} |
总结
Condition书写格式:
- 在if, for,while后面的条件,Python直接写;
- C++需要把条件写在括号()内。
代码块:
- Python使用冒号:指出接下来是一个代码块,并将代码块中的每行都缩进相同的空格(悬垂的格式);
- C++ 用{}表示代码块;