系列文章目录

一、垃圾回收机制(GC)

该机制是python解释自带的一种机制,用来自动回收不可用变量所占用的内存空间。

  • 引用计数:

    a = 10  # a是10的一个直接引用
    l = [1,2]
    l.append(a)  # 将a追加列表l中,则l间接引用了10
    a = 11  # 10的引用减1,因为a此时引用的是11
    

    ​ 当对象的引用计数为0时,该对象会被python解释器清除,内存被回收。

    ​ 循环引用会导致内存泄漏(比如,两个列表的相互引用),为此python解释器引入了标记清除方法。

  • 标记清除:

    栈区:保存变量,变量中保存着值的内存地址。在python中,a = b,实际上是将b保存的地址赋值给a,即传递的是引用(如下图)。

    堆区:保存实际的值。

    ​ python解释器会定期去栈区进行扫描,将栈区变量直接或间接引用到的堆区对象标记为存活对象(如上图的12), 其余标记为非存活(如上图的11),非存活对象会被清除。

  • 分代回收:

    ​ 以上两个方法的另一个弊端是需要大量的扫描工作,因此python解释器引入了分代回收,这里的分代是指根据变量的存活时间来对变量划分等级,存活时间越久的那一级变量,说明它们更加常用,因此对它们的扫描频率越低,从而减少扫描工作。

另外,还可以使用 del 变量名 的方法,手动删除一个变量。

二、基本输入输出

  • 接收用户输入

    使用 input 函数接收用户输入的数据,所有的输入都会保存为字符串类型

    name = input('请输入姓名:')  # 括号内写入提示信息,用户输入会保存在name变量中
    
  • 字符串的格式化输出

    1. % 号方式,在需要的地方用对应类型的%占位符占位,要传的值必须与占位符一一对应

      %s 对应字符串类型,%d 对应数字类型。

      print('My name is %s and I am %d years old'%('hugh', 18)  # 输出: My name is hugh and I am 18 years old
      

      % 在python中有特殊意义,所以不能直接打印,要打印出一个%号,需要写成 %%

    2. 使用format方法,用 {} 占位

      print('My name is {} '.format('hugh'))  # 输出: My name is hugh
      
      # 也可以传入从0开始的序号,取format方法括号内对应的值,甚至将一个值多次输出
      print('My name is {0} {0} {1} and I am {1} years old'.format('hugh', 18))  #输出: My name is hugh hugh 18 and I am 18 years old
      
      # 还可以将括号内的参数用变量保存后直接调用
      print('My name is {name} and I am {age} years old'.format(name='hugh', age=18))  #输出: My name is hugh and I am 18 years old
      
    3. 在字符串的前一位写一个 f,之后使用 { 变量名 } 将变量的值在指定的位置输出

      name = 'hugh'
      age = 18
      print(f'My name is {name} and I am {age} years old')  # 输出: My name is hugh and I am 18 years old
      
      print(f'{7+3}')  # 打印出的值为10,{} 内的内容会被当作代码执行
      

      要打印 {} 则需要写成 { {}}

三、基本运算符

  • 算数运算符

    运算符 描述 示例
    + 加法 2+3得5
    - 减法 3-2得1
    * 乘法 2*3得6
    / 除法 5/2 得2.5
    // 取整除,相除后只返回整数部分 5//2得2
    % 取余,相除后返回余数 5%2得1
    ** 2**3得8
  • 赋值运算符

    • 增量赋值

      运算符 描述 示例
      = 常规赋值 a = 5
      += 加法赋值 a += 5 相当于a = a + 5
      -= 减法赋值 a += 5 相当于a = a + 5

      还有其它算数运算符与常规赋值运算符结合形成的增量赋值运算符,用法与上面的类似。

    • 链式赋值

      x = y = z = 10  # x、y、z的值都为10
      
    • 交叉赋值

      a, b = b, a  # a和b的值被互相交换
      
    • 解压赋值

      result = 1, 2, 3  # 将多个值赋值给result,此时result为tuple类型;这一步也叫组包
      a, b, c = result  # 将result中的1,2,3按照位置关系一一赋值给a,b,c;这一步也叫拆包
      

      在拆包时,变量名和值的数量应该一致,如果做不到一致,可以使用 *变量名 接收多出来的值。

      x, y, z = {
             'a':1, 'b':2, 'c':3}  # 默认会将字典的键赋值给x,y,z
      
  • 比较运算符

    进行比较,得出真值

    运算符 描述
    > 大于
    < 小于
    == 等于
    != 不等于
    >= 大于等于
    <= 小于等于
  • 逻辑运算符

    运算符 描述
    and 布尔“与”,左右两边都为真,则运算后的值为真,其余为假
    or 布尔“或”,左右两边都为假,则运算后的值为假,其余为真
    not 布尔“非”,not 后的值,真变假,假变真
  • 位运算符

    对比二进制位,得出最终的二进制位数

    运算符 描述
    & 按位“与”,参与运算的两个值,如果两个相应位都为 1,则结果为 1,否则为 0
    | 按位“或”,只要对应的两个二进制位有一个为 1 时,结果就为 1
    ^ 按位“异或”,当两对应的二进制位相异时,结果为 1
    ~ 按位“取反”,对数据的每个二进制位取反,即把 1 变为 0,把 0 变为 1
    << “左移动”,运算数的各二进制位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃, 低位补 0
    >> “右移动”,运算数的各二进制位全部右移若干位,由“>>”右边的数指定移动的位数
  • 成员运算符

    运算符 描述
    in 当在指定的序列中找到值时返回 True,否则返回 False
    not in 当在指定的序列中没有找到值时返回 True,否则返回 False
  • 身份运算符

    运算符 描述
    is 判断两个标识符是否引用自同一个对象,若引用的是同一个对象则返回 True,否则返回 False
    is not 判断两个标识符是不是引用自不同对象,若引用的不是同一个对象则返回 True,否则返回 False
  • 运算符优先级

    优先级从高到低排序:

    运算符说明 运算符 优先级 结合性
    小括号 ( ) 19
    索引运算符 x[i] 或 x[i1: i2 [:i3]] 18
    属性访问 x.attribute 17
    乘方 ** 16
    按位取反 ~ 15
    符号运算符 +(正号)、-(负号) 14
    乘除 *、/、//、% 13
    加减 +、- 12
    位移 >>、<< 11
    按位与 & 10
    按位异或 ^ 9
    按位或 | 8
    比较运算符 ==、!=、>、>=、<、<= 7
    is 运算符 is、is not 6
    in 运算符 in、not in 5
    逻辑非 not 4
    逻辑与 and 3
    逻辑或 or 2
    逗号运算符 exp1, exp2 1

四、可变类型和不可变类型

  • 可变类型 ​

    当值改变,内存地址不变。说明对该类型变量的修改,就是对原来的值的修改(可以修改),这种数据类型就是可变类型
    如:列表list、字典dict、集合set

    ​ 注意:以上这些容器类型1仅仅是本身的地址不变,内部元素的地址是否改变,决定于元素自身是否是可变类型(箱子还是原来的箱子,里面装的东西就不一定了)

  • 不可变类型

    当值改变,内存地址也改变。说明对该类型变量的修改,只是另外申请内存空间创建了一个新的值,原来的值没有改变(不可修改),这种数据类型就是不可变类型
    如:整数int、浮点数float、字符串str、元组tuple、布尔bool

下一篇


<section class="footnotes">
  1. 容器类型指可以在一个变量中存放多个值的数据类型 ↩︎

</section>