C++程序员细学Python(一):C++与Python使用比较

平时学习使用的语言较多是C++,Python平时一般是用来简单掉包、数据分析使用的,但最近面试发现,用C++做笔试题又慢又繁琐,朋友用Python做的比我快多了(也可能因为算法实在太菜了/哭),故写该博客记录C++与Python的不同点,方便自己复习回顾。

说明:

  1. 本文适合对C++和Python都用了解的朋友;
  2. 慢慢更新ing;
  3. 博主也是菜鸟一枚,有错误希望大家严厉批评。

1.全局变量

在C++中,main函数内的变量不是全局变量,而是局部变量,只不过它的生命周期和全局变量一样长而已,而全局变量一定是定义在函数外部的。
在Python中,main函数中的变量默认为全局变量,而其他的def函数中的变量则默认为局部变量。

2.变量作用域

在C++和Python中,全局变量和局部变量用同一个名字,内层都会屏蔽外层。

int n = 1;

int main()
{
    int n = 4;
    cout << n ;
}

4
>>> a = 3
>>> def f():
...     a = 5
...     print(a ** 2)
...
>>> f()
25
>>> a
3

而在Python中有globel语句强制使局部变量转为全局变量,但一般不推荐使用:

>>> def f(x):
...     print(m)
...     m = 5
...     print(m + x)
...
>>> m = 3
>>> f(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
UnboundLocalError: local variable 'm' referenced before assignment

>>> def f(x):
...     global m
...     print(m)
...     m = 5
...     print(m + x)
...
>>> m = 3
>>> f(8)
3
13
>>> print(m)
5

3.使用函数

在C++中,调用非inline函数会将更多的东西入栈,进而在函数返回时为程序带来负担,但一般为了增强可读性,还是会选择使用函数,当然效率的降低一般可以忽略。
但在Python中,如果只是把所有代码扔进一个文件而没有把它们放进函数,那么它会因为众多的全局变量而变慢。因此,可以通过将所有代码封装、在 main函数中并调用来实现加速。

4.传址还是传值?

Python是不允许程序员选择采用传值还是传址的。Python参数传递采用的是“传对象引用”的方式,实际上,这种方式相当于传值和传址的一种综合。
如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于传址。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于传值。所以python的传值和传址是根据传入参数的类型来选择的.

定义函数:

def f(l):
    l[0] = 1

测试列表:

l = [0,1,2]
f(l)
print(l[0])
1

测试元组:

t = (0,1,2)
f(t)
print(t[0])
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-4-b8e76a0aa5a1> in <module>
      1 t = (0,1,2)
----> 2 f(t)
      3 print(t[0])


<ipython-input-2-4b9a0ca3ec49> in f(l)
      1 def f(l):
----> 2     l[0] = 1


TypeError: 'tuple' object does not support item assignment

测试自定义对象:

class A:
    x = 1
    
a = A()

def fclass(a):
    a.x = 2

fclass(a)
print(a.x)
2

测试基本类型:

def fb(x):
    x = 3
    
x = 1
fb(x)
print(x)
1

故可以进行总结:

  • 对于基本类型,函数为传值,可通过返回值获取变化后的量;
  • 对于列表、字典、自定义类型等可变对象,可以理解为传址操作;
  • 数字,字符串,元组等不可变对象,可以理解为传值操作。

5.浅拷贝还是深拷贝?

注:在python中可以用id()函数获取对象的内存地址。

测试基本数据类型:

a = 5;
b = a;
a = 6;
print(a,b)
print(id(a),id(b))
6 5
140707683383232 140707683383200

一般基本数据类型不涉及深浅拷贝问题,这里主要为了与下面对比。

测试自定义数据类型:

class A:
    def __init__(self, x):
      self.x = x
    
a = A(5)
b = a
a.x = 6
print(a.x, b.x)
b.x = 6
print(a.x, b.x)
print(id(a.x), id(b.x))
6 6
6 6
140707683383232 140707683383232

可以看出,自定义类型的拷贝只是个引用而已。

测试可变对象:

a = [1,2,3,4]
b = a
a[0] = 5
print(a[0],b[0])
b[0] = 6
print(a[0],b[0])
print(id(a),id(b))
5 5
6 6
2069683308416 2069683308416

可以看出,可变对象的拷贝也只是个引用而已。

测试不可变对象:

a = (1,2,3,4)
b = a
print(a[0],b[0])
print(id(a),id(b))
1 1
2069683361968 2069683361968

可以看出,不可变对象的拷贝也只是个引用而已,而且不可变对象引用是一件比较自然的事。

可以看到Python对拷贝这件事和C++的思路差别比较大,但我们想深拷贝怎么办?此时需要调用deepcopy进行深拷贝:

import copy

a = [1,2,3,4]
b=copy.deepcopy(a)
a[0] = 5
print(a[0],b[0])
b[0] = 6
print(a[0],b[0])
print(id(a),id(b))
5 1
5 6
2069683316352 2069682746112
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值