python语言(二)
1. python 的基础语法
1.1 编码
默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 Unicode 字符串。 当然你也可以为源码文件指定不同的编码:
# -*- coding: cp-1252 -*-
上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码,对应适合语言为保加利亚语、白罗斯语、马其顿语、俄语、塞尔维亚语。
1) 对于单个字符的编码(Python):
ord()
函数:单个Unicode字符转化十进制整数;
2) 由于Python的字符串类型是str
,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str
变为以字节为单位的bytes
。
Python对bytes
类型的数据用带b
前缀的单引号或双引号表示:
x = b'ABC'
要注意区别 ‘ABC’ 和 b'ABC',前者是 str ,后者虽然内容显示得和前者一样,但 bytes 的每个字符都只占用一个字节。
以Unicode表示的str通过encode()方法可以编码为指定的 bytes ,例如:
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
纯英文的 str 可以用 ASCII 编码为 bytes ,内容是一样的,含有中文的 str 可以用UTF-8
编码为 bytes 。
在 bytes 中,无法显示为ASCII字符的字节,用\x##
显示。我们从网络或磁盘上读取字节流,即 bytes数据。
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
如果 bytes 中只有一小部分无效的字节,可以传入errors='ignore'
忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
要计算str
包含多少个字符,可以用len()
函数:
>>> len('ABC')
3
>>> len('中文')
2
len()
函数计算的是str
的字符数,如果换成bytes
,len()
函数就计算字节数:
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6
1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。
在操作字符串时,我们经常遇到 str 和 bytes 的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对 str 和 bytes 进行转换。
3) 由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
申明了UTF-8编码并不意味着你的.py
文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码:
1.2 格式化字符串
当输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'
之类的字符串,xxx的内容都是根据变量变化的,就需要一种简便的格式化字符串的方式。
在Python中,采用的格式化方式和C语言是一致的,用%
实现,举例如下:
print() 函数使用以%
开头的转换说明符对各种类型的数据进行格式化输出。
>>>print(Hello, %s' % 'world')
'Hello, world'
>>> print('Hi, %s, you have $%d.' % ('Michael', 1000000))
'Hi, Michael, you have $1000000.
%
运算符就是用来格式化字符串的。常用的占位符如下:
转换说明符 | 替换内容 | 备注 |
---|---|---|
%d、%i | 转换为带符号的十进制整数 | 用整数替换 |
%10d | 表示输出的整数宽度至少为 10 | |
%20s | 表示输出的字符串宽度至少为 20 | |
%o | 转换为带符号的八进制整数 | |
%x、%X | 转换为带符号的十六进制整数 | |
%e | 转化为科学计数法表示的浮点数(e 小写) | |
%E | 转化为科学计数法表示的浮点数(E 大写) | |
%f、%F | 转化为十进制浮点数 | |
%g | 智能选择使用 %f 或 %e 格式 | |
%G | 智能选择使用 %F 或 %E 格式 | |
%c | 格式化字符及其 ASCII 码 | |
%r | 使用 repr() 函数将表达式转换为字符串 | |
%s | 使用 str() 函数将表达式转换为字符串 | 用字符串替换 |
- 转换说明符(Conversion Specifier)只是一个占位符,它会被后面表达式(变量、常量、数字、字符串、加减乘除等各种形式)的值代替。
- 在 print() 函数中,由引号包围的是格式化字符串,它相当于一个字符串模板,可以放置一些转换说明符(占位符)。 中间的
%
是一个分隔符,它前面是格式化字符串,后面是要输出的表达式。 - 格式化字符串中也可以包含多个转换说明符,这个时候也得提供多个表达式,用以替换对应的转换说明符;多个表达式必须使用小括号
( )
包围起来。
如果你不太确定应该用什么,%s
永远起作用,它会把任何数据类型转换为字符串:
>>> print('Age: %s. Gender: %s' % (25, True))
'Age: 25. Gender: True'
有些时候,字符串里面的%
是一个普通字符怎么办?这个时候就需要转义,用%%
来表示一个%
:
>>>print( 'growth rate: %d %%' % 7)
'growth rate: 7 %'
format()
另一种格式化字符串的方法是使用字符串的format()
方法,将传入的参数依次替换字符串内的占位符{0}
、{1}
……,不过书写麻烦:
>>> print('Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125))
'Hello, 小明, 成绩提升了 17.1%'
f-string
最后一种格式化字符串的方法是使用以f
开头的字符串,称之为f-string
,它和普通字符串不同之处在于,字符串如果包含{xxx}
,就会以对应的变量替换:
>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62
上述代码中,{r}
被变量r
的值替换,{s:.2f}
被变量s
的值替换,并且:
后面的.2f
指定了格式化参数(即保留两位小数),因此,{s:.2f}
的替换结果是19.62
。
1.3 指定对齐方式
默认情况下,print() 输出的数据总是右对齐的。也就是说,当数据不够宽时,数据总是靠右边输出,而在左边补充空格以达到指定的宽度。Python 允许在最小宽度之前增加一个标志来改变对齐方式,Python 支持的标志如下:
标志 | 说明 |
---|---|
- | 指定左对齐 |
+ | 表示输出的数字总要带着符号;正数带+ ,负数带- 。 |
0 | 表示宽度不足时补充 0,而不是补充空格。 |
几点说明:
- 对于整数,指定左对齐时,在右边补 0 是没有效果的,因为这样会改变整数的值。
- 对于小数,以上三个标志可以同时存在。
- 对于字符串,只能使用
-
标志,因为符号对于字符串没有意义,而补 0 会改变字符串的值。
n = 123456
# %09d 表示最小宽度为9,左边补0
print("n(09):%09d" % n)
# %+9d 表示最小宽度为9,带上符号
print("n(+9):%+9d" % n)
f = 140.5
# %-+010f 表示最小宽度为10,左对齐,带上符号
print("f(-+0):%-+010f" % f)
s = "Hello"
# %-10s 表示最小宽度为10,左对齐
print("s(-10):%-10s." % s)
1.4 指定小数精度
对于小数(浮点数),print() 还允许指定小数点后的数字位数,也即指定小数的输出精度。
精度值需要放在最小宽度之后,中间用点号.
隔开;也可以不写最小宽度,只写精度。具体格式如下:
%m.nf
%.nf
m 表示最小宽度,n 表示输出精度,.
是必须存在的。
f = 3.141592653
# 最小宽度为8,小数点后保留3位
print("%8.3f" % f)
# 最小宽度为8,小数点后保留3位,左边补0
print("%08.3f" % f)
# 最小宽度为8,小数点后保留3位,左边补0,带符号
print("%+08.3f" % f)
1.5 标识符
在 Python 3 中,可以用中文作为变量名,也允许 非 ASCII 标识符。
- 第一个字符必须是字母(A~Z 和 a~z)或下划线 _ ,但第一个字符不能是数字。
- 标识符的其他的部分由字母、数字和下划线组成。
- Python中的标识符中,不能包含空格、@、% 以及 $ 等特殊字符。
注意事项:
(1)在 Python 中,标识符中的字母是严格区分大小写的。两个同样的单词,如果大小格式不一样,多代表的意义也是完全不同的。
比如说,下面这 3 个变量之间,就是完全独立、毫无关系的,它们彼此之间是相互独立的个体。
number = 0
Number = 0
NUMBER = 0
(2)Python 语言中,以下划线开头的标识符有特殊含义,例如:
- 以单下划线开头的标识符(如 _width),表示不能直接访问的类属性,其无法通过 from...import* 的方式导入;
- 以双下划线开头的标识符(如__add)表示类的私有成员;
- 以双下划线作为开头和结尾的标识符(如 __init__),是专用标识符。
因此,除非特定场景需要,应避免使用以下划线开头的标识符。
(3)另外需要注意的是,Python 允许使用汉字作为标识符,例如:
C语言中文网 = "http://c.biancheng.net"
但我们应尽量避免使用汉字作为标识符,这会避免遇到很多奇葩的错误。
(4)标识符的命名,除了要遵守以上这几条规则外,不同场景中的标识符,其名称也有一定的规范可循,例如:
- 当标识符用作模块名时,应尽量短小,并且全部使用小写字母,可以使用下划线分割多个字母,例如 game_mian、game_register 等。
- 当标识符用作包的名称时,应尽量短小,也全部使用小写字母,不推荐使用下划线,例如 com.mr、com.mr.book 等。
- 当标识符用作类名时,应采用单词首字母大写的形式。例如,定义一个图书类,可以命名为 Book。
- 模块内部的类名,可以采用 "下划线+首字母大写" 的形式,如 _Book;
- 函数名、类中的属性名和方法名,应全部使用小写字母,多个单词之间可以用下划线分割;
- 常量命名应全部使用大写字母,单词之间可以用下划线分割;
1.6 python的保留字
保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
注意:如果使用 Python 中的保留字作为标识符,解释器会提示“invalid syntax” 的错误信息。
1.7 注释
Python中单行注释以 # 开头;
多行注释可以用多个 # 号,还有 ''' 和 """;
# 第一个注释
# 第二个注释
'''
第三注释
第四注释
'''
"""
第五注释
第六注释
"""
print ("Hello, Python!")
注意事项:
- 多行注释不支持嵌套;
- 注释可用来调试程序。在调试程序的过程中使用注释可以缩小错误所在的范围,提高调试程序的效率。
举个例子,如果你觉得某段代码可能有问题,可以先把这段代码注释起来,让 Python 解释器忽略这段代码,然后再运行。如果程序可以正常执行,则可以说明错误就是由这段代码引起的;反之,如果依然出现相同的错误,则可以说明错误不是由这段代码引起的。
1.8 行与缩进
python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。
缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。但具体缩进量为多少,并不做硬性规定。
if True:
print ("True")
else:
print ("False")
注意:IDLE 开发环境对缩进量的设置:
在 IDLE 开发环境中,默认是以 4 个空格作为代码的基本缩进单位。不过,这个值是可以手动改变的,在菜单栏中选择Options -> Configure
,会弹出如下对话框:

Ctrl+]
和 Ctrl+[
快捷键,此快捷键可以使所选中代码快速缩进(或反缩进)。1.9 空行
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
记住:空行也是程序代码的一部分。
1.10 同一行显示多条语句
Python可以在同一行中使用多条语句,语句之间使用分号(;)分割。
1.11 多个语句构成代码组
缩进相同的一组语句构成一个代码块,我们称之代码组。
像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。
我们将首行及后面的代码组称为一个子句(clause)。
if expression :
suite
elif expression :
suite
else :
suite
1.12 内置函数
python解释器自带的函数叫做内置函数,这些函数可以直接使用,不需要导入某个模块。
内置函数和标准库函数是不一样的。
Python 解释器也是一个程序,它给用户提供一些常用功能,并给它们起了独一无二的名字,这些常用功能就是内置函数。Python 解释器启动以后,内置函数也生效了,可以直接拿来使用。
Python 标准库相当于解释器的外部扩展,它并不会随着解释器的启动而启动,要想使用这些外部扩展,必须提前导入。Python 标准库非常庞大,包含了很多模块,要想使用某个函数,必须提前导入对应的模块,否则函数是无效的。
内置函数是解释器的一部分,它随着解释器的启动而生效;标准库函数是解释器的外部扩展,导入模块以后才能生效。
一般来说,内置函数的执行效率要高于标准库函数。
Python 解释器一旦启动,所有的内置函数都生效了;而导入标准库的某个模块,只是该模块下的函数生效,并不是所有的标准库函数都生效。
内置函数的数量必须被严格控制,否则 Python 解释器会变得庞大和臃肿。
一般来说,只有那些使用频繁或者和语言本身绑定比较紧密的函数,才会被提升为内置函数。
例如,在屏幕上输出文本就是使用最频繁的功能之一,所以 print() 是 Python 的内置函数。
Python 解释器内置了很多函数和类型,您可以在任何时候使用它们。以下按字母表顺序列出它们。
内置函数 | ||||
---|---|---|---|---|
注意: 不要使用内置函数的名字作为标识符使用(例如变量名、函数名、类名、模板名、对象名等),虽然这样做 Python 解释器不会报错,但这会导致同名的内置函数被覆盖,从而无法使用。
1.13 print输出
print(任意数据类型),主要为字符串类型和整型。
print() 函数的详细语法格式如下:
print (value,...,sep='',end='\n',file=sys.stdout,flush=False)
value 参数可以接受任意多个变量或值,因此 print() 函数完全可以输出多个值。
print 默认输出是换行的。
如果要实现不换行,可在变量末尾加上变元end=""。
print("hello" , end = "" )
若要实现数据隔开,增加变元 sep= 数据。
1.14 input输入
input() 是python的内置函数,用于从控制台读取用户输入的内容。input() 函数总是以字符串的形式来处理用户输入的内容,所以用户输入的内容可以包含任何字符。
input() 函数的用法为:
str = input(tipmsg)
说明:
- str 表示一个字符串类型的变量,input 会将读取到的字符串放入 str 中。
- tipmsg 表示提示信息,它会显示在控制台上,告诉用户应该输入什么样的内容;如果不写 tipmsg,就不会有任何提示信息。
1.15 import 与 from...import
在 python 用 import 或者 from...import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *
1.15.1 导入 sys 模块
import sys
print('================Python import mode==========================')
print ('命令行参数为:')
for i in sys.argv:
print (i)
print ('\n python 路径为',sys.path)
1.15.2 导入 sys 模块的 argv,path 成员
from sys import argv,path # 导入特定的成员
print('================python from import===================================')
print('path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path
1.16 编写 Python 源文件
交互式编程只是用来玩玩而已,真正的项目开发还是需要编写源文件的。
Python 源文件是一种纯文本文件,内部没有任何特殊格式,你可以使用任何文本编辑器打开它,比如:
- Windows 下的记事本程序;
- Linux 下的 Vim、gedit 等;
- Mac OS 下的 TextEdit 工具;
- 跨平台的 Notepad++、EditPlus、UltraEdit 等;
- 更加专业和现代化的 VS Code 和 Sublime Text(也支持多种平台)。
注意,不能使用写字板、Word、WPS 等排版工具编写 Python 源文件,因为排版工具一般都有内置的特殊格式或者特殊字符,这些会让代码变得“乱七八糟”,不能被 Python 解释器识别。
1.17 源文件的后缀
Python 源文件的后缀为.py
。任何编程语言的源文件都有特定的后缀,例如:
- C语言源文件的后缀是
.c
; - C++源文件的后缀是
.cpp
; - JavaScript 源文件的后缀是
.js
; - C# 源文件的后缀是
.cs
; - Java 源文件的后缀是
.java
。
后缀只是用来区分不同的编程语言,并不会导致源文件的内部格式发生变化,源文件还是纯文本的。
编译器(解释器)、编辑器和用户(程序员)都依赖后缀区分当前源文件属于哪种编程语言。
1.18 python编码规范
Python 采用 PEP 8 作为编码规范,其中 PEP 是 Python Enhancement Proposal(Python 增强建议书)的缩写,8 代表的是 Python 代码的样式指南。下面仅给大家列出 PEP 8 中初学者应严格遵守的一些编码规则:
(1)每个 import 语句只导入一个模块,尽量避免一次导入多个模块。
例如:
#推荐
import os
import sys
#不推荐
import os,sys
(2)不要在行尾添加分号,也不要用分号将两条命令放在同一行,例如:
#不推荐
height=float(input("输入身高:")) ; weight=fioat(input("输入体重:")) ;
建议每行不超过 80 个字符,如果超过,建议使用小括号将多行内容隐式的连接起来,而不推荐使用反斜杠 \ 进行连接。例如,如果一个字符串文本无法实现一行完全显示,则可以使用小括号将其分开显示,代码如下:
#推荐
s=("C语言中文网是中国领先的C语言程序设计专业网站,"
"提供C语言入门经典教程、C语言编译器、C语言函数手册等。")
#不推荐
s="C语言中文网是中国领先的C语言程序设计专业网站,\
提供C语言入门经典教程、C语言编译器、C语言函数手册等。"
注意,此编程规范适用于绝对大多数情况,但以下 2 种情况除外:
- 导入模块的语句过长。
- 注释里的 URL。
(3)使用必要的空行可以增加代码的可读性,通常在顶级定义(如函数或类的定义)之间空两行,而方法定义之间空一行,另外在用于分隔某些功能的位置也可以空一行。
(4)通常情况下,在运算符两侧、函数参数之间以及逗号两侧,都建议使用空格进行分隔。
x = b'ABC'
2.变量的定义和使用
任何编程语言都需要处理数据,比如数字、字符串、字符等,我们可以直接使用数据,也可以将数据保存到变量(Variable),方便以后使用。
每个变量都拥有独一无二的名字,通过变量的名字就能找到变量中的数据。
从底层看,程序中的数据最终都要放到内存(内存条)中,变量其实就是这块内存的名字。
和变量相对应的是常量(Constant)。其中变量保存的数据可以被多次修改,而常量一旦保存某个数据之后就不能修改。
- 在Python中,通常用全部大写的变量名表示常量。
- 但事实上
PI
仍然是一个变量,Python根本没有任何机制保证PI
不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量PI
的值,也没人能拦住你。
(1)python变量的赋值
在编程语言中,将数据放入变量的过程叫做赋值(Assignment)。
Python 使用等号(=)作为赋值运算符,具体格式为:
name = value
name 表示变量名;value 表示值,也就是要存储的数据。
注意,变量是标识符的一种。
(2)变量的值不是一成不变的,它可以随时被修改,只要重新赋值即可;另外你也不用关心数据的类型,可以将不同类型的数据赋值给同一个变量。
n = 10 #将10赋值给变量n
n = 95 #将95赋值给变量n
n = 200 #将200赋值给变量n
abc = 12.5 #将小数赋值给变量abc
abc = 85 #将整数赋值给变量abc
abc = "http://c.biancheng.net/" #将字符串赋值给变量abc
注意,变量的值一旦被修改,之前的值就被覆盖了,不复存在了,再也找不回了。换句话说,变量只能容纳一个值。
(3) 除了赋值单个数据,你也可以将表达式的运行结果赋值给变量,例如:
sum = 100 + 20 #将加法的结果赋值给变量
rem = 25 * 30 % 7 #将余数赋值给变量
str = "C语言中文网" + "http://c.biancheng.net/" #将字符串拼接的结果赋值给变量
(4)使用 Python 变量时,只要知道变量的名字即可。
几乎在 Python 代码的任何地方都能使用变量。
>>> n = 10
>>> print(n) #将变量传递给函数
10
>>> m = n * 10 + 5 #将变量作为四则运算的一部分
>>> print(m)
105
>>> print(m-30) #将由变量构成的表达式作为参数传递给函数
75
>>> m = m * 2 #将变量本身的值翻倍
>>> print(m)
210
>>> url = "http://c.biancheng.net/cplus/"
>>> str = "C++教程:" + url #字符串拼接
>>> print(str)
C++教程:http://c.biancheng.net/cplus/
(5) Python 是弱类型的语言
在强类型的编程语言中,定义变量时要指明变量的类型,而且赋值的数据也必须是相同类型的,C语言、C++、Java 是强类型语言的代表。
下面我们以 C++ 为例来演示强类型语言中变量的使用:
int n = 10; //int表示整数类型
n = 100;
n = "http://c.biancheng.net/socket/"; //错误:不能将字符串赋值给整数类型
url = "http://c.biancheng.net/java/"; //错误:没有指明类型的变量是没有定义的,不能使用。
和强类型语言相对应的是弱类型语言,Python、JavaScript、PHP 等脚本语言一般都是弱类型的。
(6)弱类型语言有两个特点:
- 变量无须声明就可以直接赋值,对一个不存在的变量赋值就相当于定义了一个新变量。
- 变量的数据类型可以随时改变,比如,同一个变量可以一会儿被赋值为整数,一会儿被赋值为字符串。
注意,弱类型并不等于没有类型!弱类型是说在书写代码时不用刻意关注类型,但是在编程语言的内部仍然是有类型的。我们可以使用 type() 内置函数类检测某个变量或者表达式的类型,例如:
>>> num = 10
>>> type(num)
<class 'int'>
>>> num = 15.8
>>> type(num)
<class 'float'>
>>> num = 20 + 15j
>>> type(num)
<class 'complex'>
>>> type(3*15.6)
<class 'float'>
Python 具备多种可实现数据类型转换的函数:
函 数 | 作 用 |
---|---|
int(x) | 将 x 转换成整数类型 |
float(x) | 将 x 转换成浮点数类型 |
complex(real,[,imag]) | 创建一个复数 |
str(x) | 将 x 转换为字符串 |
repr(x) | 将 x 转换为表达式字符串 |
eval(str) | 计算在字符串中的有效 Python 表达式,并返回一个对象 |
chr(x) | 将整数 x 转换为一个字符 |
ord(x) | 将一个字符 x 转换为它对应的整数值 |
hex(x) | 将一个整数 x 转换为一个十六进制字符串 |
oct(x) | 将一个整数 x 转换为一个八进制的字符串 |