抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

本篇笔记主要记录python基础的运算符和函数参数传递,以及自己学习过程的一些思考。

1. 运算符

1.1 比较运算符

python中常见的比较运算符如下:

  1. == 检查左右两个值是否相等,相等则返回True
  2. != 检查左右两个值是否相等,不相等则返回True
  3. <> 和 != 一样,检查两个值是否相等,不相等返回True
  4. >= 字面意思,字面意思的还有<=、 < 和 >

1.2 算数运算符

python常见的算数运算符:

  1. / 两个数相除,结果为浮点型
  2. // 两个数相除,结果为向下取整的整数
  3. % 取模,也就是两个整数相除的余数
  4. ** 幂运算,返回乘方的结果
  5. + 两个数相加,或者字符串相连
  6. * 两个数相乘,或者返回重复若干次的字符串
  7. - 字面意思,两个数相减

1.3 赋值运算符

顾名思义都是在赋值的时候用到的运算符

  1. = 常规赋值运算,运算结果赋值给变量
  2. += 加法赋值运算,a += b等效于a = a+b
  3. 其他算数运算符都可以后面跟上=,进行运算后赋值

1.4 位运算符

按位运算就是将数字转换为二进制来运算的运算形式,数值是用补码来表示和存储的,计算机用位运算符进行四则运算速度快。但是我们平常可能用不到,这里稍微记录一下。

  1. & 按位“与”:两个值如果相应位都为1,则结果为1,否则0
  2. | 按位“或”:两个值相应位有一个位1,结果就为1
  3. ^ 按位“异或”:两个值相应位相异,结果为1
  4. ~ 按位“取反”:对数据的每个二进制位取反
  5. << 左移运算符:运算数的二进制全部座椅若干位,高位丢弃,低位补0;>>右移同理

1.5 逻辑运算符

  1. and 逻辑“与”,两个都为True则返回True,否则False
  2. or 逻辑“或”,两个至少有一个True则返回True,否则False
  3. not 逻辑“非”,字面意思

1.6 成员和身份运算符

python的成员运算符用来判断一个数据是否在指定的序列或者集合中,而身份运算符是用来判断两个变量是否引用自同一个对象。

  1. in 成员运算符,在指定序列中找到值则返回True,否则False
  2. not in 成员运算符,在指定序列中没有找到值则返回True,否则False
  3. is 身份运算符,两个标识符是否引自同一个对象,是则返回True,否则False
  4. is not 身份运算符,两个标识符是否引用同一个对象,不是则返回True,否则False

是否引自同一个对象,简单理解就是看存储的内存位置是否一样,通过函数id()可以查看变量在内存中的存储位置。

2. 参数传递

要理解参数传递的过程,首先要明白关于函数参数的两个具体概念:形参和实参

  • 定义时小括号中的参数,是用来接收参数的,称为“形参”,可以是缺省参数、不定长参数
  • 调用时小括号中的参数,是用来传递参数给函数的,称为“实参”

向函数传递实参的方式很多,确定传递参数个数可以使用位置实参或者关键字实参,不确定传递参数个数可以使用包裹(packing)传递的方式,来包裹位置或者关键字实参,进行参数传递。

2.1 位置实参

函数调用时每个实参都要关联到函数定义中的一个形参,最简单的是按照形参的位置从左到右按照顺序传递,位置参数必须一一对应,缺一不可。

比如上面创建了一个describe_me()函数,形参定义了需要name和age两个参数,因此在调用这个函数的时候要按照顺序提供这两个参数。在上例中,从左到右实参‘Phantom’储存在形参name中,实参26储存在形参age中,参数传递本质上就是实参到形参的赋值操作

2.2 关键字实参

关键字实参顾名思义是传递函数的key-Value对,在实参中将关键字和值关联,因为这种对应关系是唯一的,在调用函数的时候就不需要考虑实参的顺序。

这种参数传递方式比较直观,能一眼看出函数调用时各个值对应的用途。

关键字实参和位置实参时可以一起使用,需要注意:

  • 关键字实参必须在位置实参右边(写的时候位置实参优先
  • 对同一个形参不可重复传值

2.3 形参的缺省

创建函数的时候可以给形参指定默认值(缺省)。

对于缺省形参,需要注意:

  • 缺省参数要在非缺省参数之后(缺省形参放右边)
  • 缺省参数是可选参数,可以不传;如果传入则按照传入的值进行运算

2.4 形参的不定长参数(包裹传递)

当传入的参数个数不确定时,可以使用包裹位置参数和包裹关键字参数进行参数传递。

  • *+形参的方式传递参数,传入后根据参数的位置以元组形式保存
  • **+形参的方式传递参数,需要使用关键字,传入后以字典形式保存,形参名字是传入字典的键

上面例子形参中的args表示arguments位置参数,kargs表示key arguments关键字参数,这个是可以自定义的。

不同的参数传递方式可以混用,原则上要遵循位置参数,默认参数,包裹位置,包裹关键字的顺序。

1
def func(name, age = 26, *args, **kargs)  # 定义和调用都遵循这样的顺序

2.5 对传参的思考

在CSDN上看到一个总结写的很好,函数的参数传递本质上是从实参到形参的赋值操作,而所有的赋值操作都是“引用的赋值”,因此Python中参数的传递都是“引用传递”,不是“值传递”。这句话初看有点难以理解,首先看看什么是引用传递和值传递:

  • 值传递(pass by value):调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
  • 引用传递(pass by reference):调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

根本区别在于引用传递不创建副本,最直接的理解方式就是通过查看对象的地址,看看传参前后对象在内存的位置是否改变。

2.5.1 可变对象的传递

复习一下,可变对象有列表、字典和集合,我们这里以列表为例。

可以看到,如果传递的对象是可变对象,实际上传递的是对象的引用(不创建副本,传递前后在内存中存储位置不变),在函数中修改对象后,直接在原始对象上做了相应的修改

2.5.2 不可变对象的传递

如果传递的对象是不可变类型,比如元组,字符和数字,这里以数字为例。

可以看到,如果传递的对象是不可变对象,传进函数的时候同样是对象的引用,但是不可变对象无法修改,因此在赋值操作时,系统新创建了一个对象(和原来a的存储地址不同)进行赋值,而原始对象并没有改变

也就是说,不可变对象的传递起到类似值传递的效果,但是实际上依然是引用传递的方式进行传参。

欢迎小伙伴们留言评论~