赋值语句
赋值语句建立对象引用值
变量名在首次赋值时会被创建
变量名在引用前必须先赋值
执行隐式赋值的一些操作:显示赋值由“=”连接,隐式赋值如:模块导入,函数和类的定义,for循环变量以及函数参数全都是隐式赋值运算。因为赋值语句在任何出现的地方的工作原理都相同,所有这些环境都是在运行时把变量名和对象的引用值绑定起来而已
运算 | 解释 |
spam = 'Spam' | 基本形式 |
spam, ham = 'Spam', 'Ham' | 元组赋值运算(位置性) |
[spam, ham] = ['yum', 'YUM'] | 列表赋值运算(位置性) |
a, b, c, d = 'spam' | 序列赋值运算,通用性 |
a, *b = 'spam' | 扩展的序列解包 |
spam = ham = 'lunch' | 多目标赋值运算 |
a += 43 | 增强赋值运算,等价于a=a+43 |
增强赋值形式输入较少,而且通常执行的更快。在python中,每个二元表达式运算符都有增强赋值语句(+=,*=,**=,&= ...)。
序列赋值语句实际上支持右侧任何可迭代对象:
[a, b, c] = (1, 2, 3)
(a, b, c) = "ABC"
a, b, c = range(3)
扩展序列解包:
>>> seq = [1, 2, 3, 4]
>>> a, b, c, d = seq
>>> print(a, b, c, d)
1 2 3 4
>>> a, b = seq
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
a, b = seq
ValueError: too many values to unpack (expected 2)
>>> a, *b = seq
>>> a
1
>>> b
[2, 3, 4]
>>> *a, b = seq
>>> a
[1, 2, 3]
>>> b
4
>>> a, *b, c = seq
>>> b
[2, 3]
序列解包VS分片
>>> a, *b, c = 'spam'
>>> a, b, c
('s', ['p', 'a'], 'm')
>>> S = 'spam'
>>> S[0], S[1:3], S[3]
('s', 'pa', 'm')
相似但不完全相同,一个序列解包赋值总是返回多个匹配项的一个列表,而分片把相同类型的一个序列作为分片的对象返回。
边界情况:
尽管扩展的序列解包很灵活,一些边界情况还是要注意。
带星号的名称可能只匹配单个的项,都是总是会向其赋值一个列表
如果没有剩下的内容可以匹配嗲星号的名称,它会赋值一个空的列表
>>> seq
[1, 2, 3, 4]
>>> a, b, c, *d = seq
>>> a, b, c, d
(1, 2, 3, [4])
>>> a, b, c, d, *e = seq
>>> a, b, c, d, e
(1, 2, 3, 4, [])
注意如下几种情况:
>>> a, *b, c, *d =seq #多个星号
SyntaxError: two starred expressions in assignment
>>> a, b = seq #值少了而没有星号
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
a, b = seq
ValueError: too many values to unpack (expected 2)
>>> *a = seq #带星号的名称紫色没有编写到一个列表中
SyntaxError: starred assignment target must be in a list or tuple
>>> *a, = seq #这个ok
>>> a
[1, 2, 3, 4]
多目标赋值语句:
a = b = c = 'spam'
多目标赋值以及共享引用:
注意,这里只有一个对象,由三个变量共享(全都指向内存同一对象)。这种行为对于不可变类型没问题,若是可变对象,那么一处修改,三处共享结果。
变量命名规则:
语法:(下划线或字母)+(任意数目的字母,数字或下划线)
区分大小写
禁止使用保留字
False | class | finally | is | return |
None | continue | for | lambda | try |
True | def | from | nonlocal | while |
and | del | global | not | with |
as | elif | if | or | yield |
assert | else | import | pass | break |
except | in | raise |
此外,因为import语句中的模块变量名会变成脚本的变量,这种限制也会扩展到模块的文件名:你可以写and.py等文件,但是你无法将他们导入,因为其变量名没有.py扩展名时,就会变成代码中的变量。
命名惯例‘
变量名前后有下划线时,如__name__,通常对解释器有特殊意义,你应该避免使用这种样式。
以下是Python遵循的一些惯例:
以单一下划线开头的变量(_x)不会被from modle import * 语句导入
前后有下划线的变量名是系统定义的变量名
以双下划线开头,结尾没下划线的变量名,是类的本地变量
其他惯例:
类变量名通常以一个大写字母开头,模块变量名以小写字母开头。self虽非保留字,但在类中一般有特殊的角色。内置变量名,这些是预先定义的变量名,但并非保留字(所以可以重新赋值 open = 42行得通,但是这样做之后可能不能打开文件了)
变量名没有类型,它只是对象的引用值,类型是跟对象绑定在一起的。
表达式语句:
运算 | 解释 |
spam(eggs, ham) | 函数调用 |
spam.ham(eggs) | 方法调用 |
spam | 在交互模式解释器内打印变量 |
print(a, b, c, sep=' ') | 打印 |
yield x**2 | 产生表达式的语句 |
Python工作中常犯的错误,表达式语句通常用于执行可于原处修改列表的列表方法:
>>> ll = [1,2]
>>> ll.append(3)
>>> ll
[1, 2, 3]
>>> ll = ll.append(4) #append return None
>>> print(ll)
None
打印
写入文件的文件对象方法(如file.write(str))。打印操作类似,但更加专注--文件写入方法是把字符串写入任意的文件,print默认把对象打印到stdout流,添加了一下自动的格式化,不需要把对象转换为字符串。
print([object,...][, sep=' '][, end='\n'][, file=sys.stdout])
sep, end, file部分如果给出的话,必须作为关键字参数给定。
print(a, b, c, sep='...', end='--', file=open('data.txt', 'w')
这里打印的过程中,把文本打印到一个输出文件或者其他的可兼容对象(其他是流定向的一种形式)
Learning Python, Fourth Edition, by Mark Lutz.