Python从入门到精通(微课精编版)
上QQ阅读APP看书,第一时间看更新

2.2 变量

2.2.1 认识变量

在C/C++语言中,变量的概念是面向内存的,需要先声明一个变量,定义存储空间大小、存储的格式(如整数、浮点数等),以及一个永久不变的名称指向这个变量。而在Python语言中,变量是一个仅有名称的标签,记录了对一个对象的引用,变量自身没有空间大小和类型的概念。

与变量相关的4个概念简单区别如下。

➢ 变量名称。

➢ 变量的值,指引用对象包含的数据。

➢ 变量类型,指引用对象的类型,使用内置函数type()可以查看变量的类型。

➢ 变量地址,指引用对象的内存地址,使用内置函数id()可以查看变量的地址。

因此,变量被赋值后才能确定类型。例如,n=1,数字1是整数,那么变量n的类型就是整型;s="hi","hi"是字符串,那么变量s的类型就是字符串型;b=False,False是布尔值,那么变量b的类型就是布尔型。

在Python中,不需要声明变量,也不需要定义变量类型,但是变量在使用前必须要赋值,然后才能使用。使用赋值运算符,直接把对象赋值给变量就可以定义一个变量。语法格式如下:

    变量名称 = 对象

等号左侧是一个变量名称,右侧是一个对象。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用赋值给变量。

注意:赋值是一条语句,不是一个表达式,因此,赋值不能当作表达式参与运算。例如,下面写法将抛出语法错误。

    y = (x = 1)

【示例1】下面示例中a和b属于不同的类型,不能执行比较运算,在运行时Python不会隐式转换其中一个变量的类型,而是直接抛出TypeError异常。

    a = 1
    b = "1"
    a < b

【示例2】运行下面代码时不会报错,因为Python动态改变变量的类型。

    n = 10
    print(type(n))          # 输出 <class 'int'>
    n = "10"
    print(type(n))          # 输出 <class 'str'>

2.2.2 命名变量

变量名字是有效标识符,第一个字符必须是字母或下画线(_),其余字符可以由字母、数字或下画线组成,并严格区分大小写。例如:

    abc_123 = 10          # 变量命名正确
    123_abc=10            # 变量命名不合法
    _abc123=10            # 变量命名正确

变量名没有长度限制,但是不能使用Python关键字和保留字,也不建议使用Python内置函数,这样会导致内置函数被覆盖,例如:

    if = 10               # if是关键字
    print=10              # 给print函数赋值,编译可以通过
    print(print)          # 函数被覆盖,编译报错

变量命名原则:能够见名知意。例如,表示名称的变量可命名为name,表示性别的变量可以命名为sex,表示学生的变量可以命名为student等。

变量命名的一般方法是驼峰式命名法。包括如下两种形式。

(1)小驼峰式命名法:第一个单词以小写字母开始,第二个单词的首字母大写。例如:

    firstName
    lastName

(2)大驼峰式命名法:每一个单词的首字母都采用大写字母。例如:

    FirstName
    LastName

也可以使用下画线(_)连接多个单词,例如:

    first_name
    last_name

【示例】下面示例演示了一个简单的购物车计算过程。

    price = 10                      # 商品价格
    weight = 20                     # 商品重量
    money = price * weight          # 购买金额
    money -= 5                      # 促销返款
    print(money)                    # 显示实际金额,输出为  195

2.2.3 变量赋值

除了直接为单个变量赋值外,Python也允许同时为多个变量赋值。具体有如下两种形式。

1.链式赋值

【示例】下面示例为变量a、b、c同时赋值字符串"abc"。

    a = b = c = "abc"          # a、b、c分别为"abc"、"abc"和"abc"

这种形式也称为多重赋值。

2.解包赋值

解包就是将容器的元素逐一赋值给多个元素。例如:

    a, b, c = [1,2,3]          # 列表解包,a、b、c分别为1、2、3

列表中有3个元素,刚好可以分配给3个变量。除了列表对象可以解包之外,任何可迭代对象都支持解包,如元组、字典、集合、字符串、生成器等,也就是实现了__next__()方法的一切对象。例如:

    a,b,c = (1,2,3)                        # 元组解包,a、b、c分别为1、2、3
    a,b,c = "abc"                          # 字符串解包,a、b、c分别为"a"、"b"和"c"
    a,b,c = {"a":1, "b":2, "c":3}          # 字典解包,a、b、c分别为"a"、"b"和"c"

字典解包后,只把字典的键取出来,值则丢掉。

另外,如果是元组,则可以省略小括号,类似多变量赋值操作,例如:

    a,b,c = 1,2,3          # 多变量赋值,a、b、c分别为1、2、3

其本质上也是自动解包过程,等号右边其实是一个元组对象(1,2,3)。如果是下面写法,就变成了元组对象。

    a = 1,          # a为元组对象(1,)

在Python中,交换两个变量非常方便,本质上也是自动解包过程。

    a, b = 1, 2
    a, b = b, a          # 元组解包,a、b分别为2、1

注意:在解包过程中,如果遇到左边变量个数小于右边可迭代对象中元素的个数时,可以在某个变量前添加星号前缀。例如:

    a, b, *c = [1,2,3,4]          # a、b、c分别为1、2、[3, 4]

星号可以放在任意变量前,它表示每个变量都分配一个元素后,剩下的元素都分配给这个带星号的变量。例如:

    a, *b, c = [1,2,3,4]          # a、b、c分别为1、[2, 3]、4

在解包过程中,如果遇到左边变量的个数大于右边可迭代对象中元素的个数时,可以在某个变量前面添加星号前缀。例如:

    a, b, *c = [1,2]              # a、b、c分别为1、2、[]

但是,没有星号的变量必须保证能够分配一个元素值,否则将抛出异常。