本节目标:
学习Python最基础的语法知识,可以用代码快速实现一些简单的功能
内容概要:
输入和输出
初识数据类型
变量
注释
运算符
格式化输出
一、输入和输出
1. 输出——print
1 | print(self, *args, sep=' ', end='\n', file=None): # known special case of print |
1.1 将结果或内容呈现给用户
1 | print(" _ooOoo_ ") |
1.2 关于输出
默认print在尾部会加换行符
1
2
3
4
5
6
7
8
9
10print('文能提笔安天下,')
print('武能上马定乾坤。')
print('心存谋略何人胜,')
print('古今英雄唯是君。')
输出:
文能提笔安天下,
武能上马定乾坤。
心存谋略何人胜,
古今英雄唯是君。想要不换行,则可以这样做
1
2
3
4
5
6
7print('文能提笔安天下,', end='')
print('武能上马定乾坤。', end='')
print('心存谋略何人胜,', end='')
print('古今英雄唯是君。', end='')
输出:
文能提笔安天下,武能上马定乾坤。心存谋略何人胜,古今英雄唯是君。1
2
3
4
5
6
7print('文能提笔安天下', end=',')
print('武能上马定乾坤', end='。')
print('心存谋略何人胜', end=',')
print('古今英雄唯是君', end='。')
输出:
文能提笔安天下,武能上马定乾坤。心存谋略何人胜,古今英雄唯是君。
2. 输入——input
1 | input(*args, **kwargs) |
可以实现程序与用户之间的交互
1
2
3
4
5
6
7
8
9#1.使用input获取必要的信息
name =input("请输入名字:")
qq=input("请输入qq:")
#2.使用print来打印名片
print("="*20)
print("姓名:%s"%name)
print("qq:%s"%qq)
print("="*20)输入密码时,如果想要不可见,需要利用
getpass
模块中的getpass
方法,即:1
2
3
4
5import getpass
username = input('请输入用户名:')
pwd = getpass.getpass('请输入密码:')
print(username,pwd)特别注意:用户输入的任何内容本质上都是字符串。
二、初识数据类型
上学时,老师叫我们数字、拼音、汉字、真假判断等,然后我们根据学到的内容写作文,老师来检查并打分。现在学编程,教大家int、str、bool等,然后大家根据这些内容来写代码,写完代码交给Python解释器去运行。Python中的数据类型很多,而且也允许我们自定义新的数据类型(这一点在后面会讲到),我们先介绍几种常用的数据类型。
- 整型:Python中可以处理任意大小的整数(Python 2.x中有
int
和long
两种类型的整数,但这种区分对Python来说意义不大,因此在Python 3.x中整数只有int这一种了),而且支持二进制(如0b100
,换算成十进制是4)、八进制(如0o100
,换算成十进制是64)、十进制(100
)和十六进制(0x100
,换算成十进制是256)的表示法。 - 浮点型:浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,浮点数除了数学写法(如
123.456
)之外还支持科学计数法(如1.23456e2
)。 - 复数型:形如
3+5j
,跟数学上的复数表示一样,唯一不同的是虚部的i
换成了j
。实际上,这个类型并不常用,大家了解一下就可以了。 - 字符串型:字符串是以单引号或双引号括起来的任意文本,比如
'hello'
和"hello"
,字符串还有原始字符串表示法、字节字符串表示法、Unicode字符串表示法,而且可以书写成多行的形式(用三个单引号或三个双引号开头,三个单引号或三个双引号结尾)。 - 布尔型:布尔值只有
True
、False
两种值,要么是True
,要么是False
,在Python中,可以直接用True
、False
表示布尔值(请注意大小写),也可以通过布尔运算计算出来(例如3 < 5
会产生布尔值True
,而2 == 1
会产生布尔值False
)。
1. Number(数字)
Python3 支持 int、float、complex(复数)。在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。像大多数语言一样,数值类型的赋值和计算都是很直观的。内置的 type() 函数可以用来查询变量所指的对象类型。
定义:
1
2
3
4
5
6
7# 整型 int
print(666)
# 小数 float
print(11.11)
# 复数 complex
print(complex(2, -4))
print(2 - 4j)整型的运算
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 整型加法
print(2 + 10)
# 整型减法
print(10 - 2)
# 整型乘法
print(2 * 10)
# 整型除法
print(10 / 2)
# 整型求商/取整
print(10 // 2)
# 整型取余/取模
print(10 % 3)
# 幂运算 x ** y x的y次方
print(2 ** 4)注意:
- 1、Python可以同时为多个变量赋值,如a, b = 1, 2。
- 2、一个变量可以通过赋值指向不同类型的对象。
- 3、数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。
- 4、在混合计算时,Python会把整型转换成为浮点数。
判断类型
1
2
3
4a, b, c = 20, 5.5, 4+3j
print(type(a), type(b), type(c))
# 输出
# <class 'int'> <class 'float'> <class 'bool'> <class 'complex'>此外还可以用
isinstance
来判断:1
2
3a = 111
print(isinstance(a, int))
# Trueisinstance
和type
的区别在于:type()
不会认为子类是一种父类类型。isinstance()
会认为子类是一种父类类型。
1
2
3
4
5
6
7
8
9
10
11
12
13class A:
pass
class B(A):
pass
print(isinstance(A(), A))
# True
print(type(A()) == A)
# True
print(isinstance(B(), A))
# True
print(type(B()) == A)
# False
2. 字符串(str)
字符串,其实就是生活中的文本信息,例如:姓名、地址、自我介绍等。
字符串有一个特点,他必须由引号引起来,引号可以是’x’、”x”、’’’x’’’、”””x”””如:
单行字符串
1
2
3
4print('我是张亚飞')
print("我是张亚飞")
print("我是'张亚飞'")
print('我是"张亚飞"')多行字符串
1
2
3
4
5
6
7
8
9
10
11print("中国山西晋中市")
print('''中国山西晋中市
xxxxxxxxx
xxxxxxxx
xxxxxxx
''')
print("""中国山西晋中市
xxxxxxxxx
xxxxxxxx
xxxxxxx
""")
对于字符串
加,两个字符串可以通过加好拼接起来。
1
print("君子" + "成人之美")
乘,整型和字符串相乘,以实现让字符串重复出现N次并拼接起来。
1
2
3
4
5
6print("我想吃饺子我想吃饺子我想吃饺子我想吃饺子")
print('我想吃饺子' * 4)
输出
我想吃饺子我想吃饺子我想吃饺子我想吃饺子
我想吃饺子我想吃饺子我想吃饺子我想吃饺子
3. 布尔类型
布尔类型中共有两个值:True/False
1 | print(1 > 2) |
- 补充
1 | print('hello' > 'world') |
进行逻辑判断(比如if)时,Python当中等于False的值并不只有False一个,它也有一套规则。对于基本类型来说,基本上每个类型都存在一个值会被判定为False。大致是这样:
- 布尔型,False表示False,其他为True
- 整数和浮点数,0表示False,其他为True
- 字符串和类字符串类型(包括bytes和unicode),空字符串表示False,其他为True
- 序列类型(包括tuple,list,dict,set等),空表示False,非空表示True
- None永远表示False
自定义类型则服从下面的规则:
- 如果定义了nonzero()方法,会调用这个方法,并按照返回值判断这个对象等价于True还是False
- 如果没有定义nonzero方法但定义了len方法,会调用len方法,当返回0时为False,否则为True(这样就跟内置
- 类型为空时对应False相同了)
- 如果都没有定义,所有的对象都是True,只有None对应False
注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。
1
True + True # 1 + 1 = 2
4. 类型转换
上文对数据类型int/str/bool有了初步了解,他们都有自己的定义方式:
- int,整数定义时,必须是数字且无引号,例如:5,8,9
- str,字符串定义时,必须用双引号括起来,例如:”中国”,”陈月”,”666”
- bool,布尔值定义时,只能写True和False
不同数据类型有不同的功能,例如:整型可以加减乘除而字符串只能加(拼接)和乘法。
如果想要做转换可遵循一个基本规则:想转换什么数据类型就让他包裹一层该数据类型。
例如:str(666) == “666”是让整型咋混换为字符串,int(‘888’) == 888是字符串转整型。
转换为整型
1
2
3
4
5
6
7
8
9
10
11
12# 字符串转换为整型(渡可渡之人)
int('666')
int('999')
'6' + '9' == '69'
int('6') + int('9') == 15
int('今天天气真好') # 报错
# 布尔类型转换为整型
int(True) 转换完等于1
int(False) 转换完等于0转换为字符串
1
2
3
4
5
6
7# 整型转字符串
str(234)
str(666) + str(999) 结果为 '666999'
# 布尔类型转换为字符串
str(True) "True"
str(False) "False"转换为布尔类型
1
2
3
4
5
6
7
8
9
10
11# 整型转布尔
bool(1) True
bool(2) True
bool(0) False
bool(-10) True
# 字符串转布尔
bool('nice') True
bool('自作自受') True
bool('') False
bool(' ') True三句话搞定类型转换
- 其他所有类型转换为布尔类型时,除了空字符串、0以为其他都是True。
- 字符串转整型时,只有那种”888”格式的字符串才可以转换为整型,其他都报错。
- 想要转换为哪种类型,就用这类型的英文包裹一下就行。
1
2
3str(...)
int(...)
bool(...)
三、变量
在程序设计中,变量是一种存储数据的载体。计算机中的变量是实际存在的数据或者说是存储器中存储数据的一块内存空间,变量的值可以被读取和修改,这是所有计算和控制的基础。变量,其实就是我们生活中起别名和外号,让变量名指向某个值,格式为:【变量名=值】,以后可以通过变量名来操作其对应的值。
1 | name = '张亚飞' |
1 | age = 18 |
注意:
- 给变量赋值age = 18
- 让age代指值age = 18
1. 变量名的规范
1 | age = 18 |
1.1 硬性规范:(不符合规范会报错)
变量名只能有字母、数字、下划线组成
不能以数字开头
不能用Python内置关键字
1
2
3
4
5
6
7
8
9
10
11
12
13In [3]: help('keywords')
Here is a list of the Python keywords. Enter any keyword to get more help.
False def if raise
None del import return
True elif in try
and else is while
as except lambda with
assert finally nonlocal yield
break for not
class from or
continue global pass
1.2 PEP8变量命名建议:
用小写字母拼写,多个单词用下划线连接。
1
2
3
4englishScore = 100 #小驼峰
english_score = 100 #下划线,推荐
EnglishScore = 100 #大驼峰
englishscore = 100 #不推介受保护的实例属性用单个下划线开头(后面会讲到)
私有的实例属性用两个下划线开头(后面会讲到)。
其他规范:
- 当然,作为一个专业的程序员,给变量(事实上应该是所有的标识符)命名时应做到见名知意。
2. 变量的使用
下面通过几个例子来说明变量的类型和变量使用。
1 | # 不使用变量 |
在Python中可以使用type
函数对变量的类型进行检查。程序设计中函数的概念跟数学上函数的概念是一致的,数学上的函数相信大家并不陌生,它包括了函数名、自变量和因变量。如果暂时不理解这个概念也不要紧,我们会在后续的章节中专门讲解函数的定义和使用。
1 | """ |
可以使用Python中内置的函数对变量类型进行转换。
int()
:将一个数值或字符串转换成整数,可以指定进制。float()
:将一个字符串转换成浮点数。str()
:将指定的对象转换成字符串形式,可以指定编码。chr()
:将整数转换成该编码对应的字符串(一个字符)。ord()
:将字符串(一个字符)转换成对应的编码(整数)。
下面的代码通过键盘输入两个整数来实现对两个整数的算术运算。
1 | """ |
说明:上面的print函数中输出的字符串使用了占位符语法,其中
%d
是整数的占位符,%f
是小数的占位符,%%
表示百分号(因为百分号代表了占位符,所以带占位符的字符串中要表示百分号必须写成%%
),字符串之后的%
后面跟的变量值会替换掉占位符然后输出到终端中,运行上面的程序,看看程序执行结果就明白啦。
3. 变量内存指向关系
学习上述变量知识让我们对变量有了初步认识,接下来我们从稍微高级点的角度来学习变量。即内存指向(在电脑内存中是怎么存储的)。
3.1 情景一:
1 | name = 'zhangyafei' |
在计算机内存中创建一块区域保存字符串“zhangyafei
”,name变量名则指向这块区域。

3.2 情景二:
1 | name = 'zhangyafei' |
在计算机内存中创建一块区域保存字符串‘zhangyafei’,name变量名则指向这块区域。然后又再向内存中创建了一块区域保存字符串‘’xiaoming”,name变量名则指向”xiaoming“所在的区域,不再指向”zhangyafei“所在区域(无人指向的数据会被标记为垃圾,由解释器自动化回收)
3.3 情景三:
1 | name = 'zhangyafei' |
在计算机内存中创建一块区域保存字符串‘zhangyafei’,name变量名则指向这块区域。new_name变量名指向name变量,因为被指向的是变量名,所以自动转指向到name变量代表的内存区域。
3.4 情景四:
1 | name = 'zhangyafei' |
在计算机内存中创建一块区域保存字符串‘zhangyafei’,name变量名则指向这块区域。new_name变量名指向name所指向的内存区域,最后又创建了一个区域存放’xiaoming‘,让name变量指向xiaoming’所在区域。
3.5 情景五:
1 | num = 18 |
在计算机的内存中创建一块区域保存整型18,name变量名则指向这块区域。通过类型转换依据整型18再在内存中创建一个字符串“18”,age变量指向保存这个字符串的内存区域。
四、注释
写代码时候如果想要对某内容进行注释处理,及:解释器忽略不会按照代码去执行
单行注释:# 注释内容
1
2
3
4
5
6# 声明一个name含量
name = 'xiaoming'
age = 19 # 当前用户年龄
注意:快键键 command + ? 和ctrl + ?多行注释:三个单引号或三个双引号内添加多行注释内容
1
2
3
4
5
6
7
8
9
10
11# 声明一个name含量
# 声明一个name含量
# 声明一个name含量
name = 'xiaoming'
"""
多行注释内容
多行注释内容
多行注释内容
"""
age = 19 # 当前用户年龄
五、运算符
什么是运算符呢?
1 | 4 + 5 = 9 |
例子中,4 和 5 被称为操作数,+ 称为运算符。
Python支持多种运算符,本节内容将包含以下内容:
- 算数运算符
- 比较运算符
- 赋值运算符
- 逻辑运算符
- 位运算符
- 成员运算符
- 身份运算符
- 运算符优先级
1. 算数运算符
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果 31 |
- | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
/ | 除 - x 除以 y | b / a 输出结果 2.1 |
% | 取模 - 返回除法的余数 | b % a 输出结果 1 |
** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
// | 取整除 - 向下取接近商的整数 | >>> 9//2 4 >>> -9//2 -5 |
2. 比较运算符
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True。 |
> | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
< | 小于 - 返回x是否小于y。 | (a < b) 返回 True。 |
>= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
<= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
比较运算符有的地方也称为关系运算符,包括==
、!=
、<
、>
、<=
、>=
,我相信没有什么好解释的,大家一看就能懂,唯一需要提醒的是比较相等用的是==
,请注意这个地方是两个等号,因为=
是赋值运算符,我们在上面刚刚讲到过,==
才是比较相等的比较运算符。比较运算符会产生布尔值,要么是True
要么是False
。
3. 赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c *= a 等效于 c = c * a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
:= | 海象运算符,可在表达式内部为变量赋值。 |
海象运算符的三种用法
用法1:if/else
在 Golang 中的条件语句可以直接在 if 中运算变量的获取后直接对这个变量进行判断,可以让你少写一行代码
1
2
3
4
5
6
7import "fmt"
func main() {
if age := 20;age > 18 {
fmt.Println("已经成年了")
}
}若在 Python 3.8 之前,Python 必须得这样子写
1
2
3age = 20
if age > 18:
print("已经成年了")但有了海象运算符之后,你可以和 Golang 一样(如果你没学过 Golang,那这里要注意,Golang 中的
:=
叫短变量声明,意思是声明并初始化,它和 Python 中的:=
不是一个概念)1
2if (age:= 20) > 18:
print("已经成年了")用法2:while
在不使用 海象运算符之前,使用 while 循环来读取文件的时候,你也许会这么写
1
2
3
4
5
6file = open("demo.txt", "r")
while True:
line = file.readline()
if not line:
break
print(line.strip())但有了海象运算符之后,你可以这样
1
2
3file = open("demo.txt", "r")
while (line := file.readline()):
print(line.strip())使用它替换以往的无限 while 循环写法更为惊艳
比如,实现一个需要命令行交互输入密码并检验的代码,你也许会这样子写
1
2
3
4while True:
p = input("Enter the password: ")
if p == "youpassword":
break有了海象运算符之后,这样子写更为舒服
1
2while (p := input("Enter the password: ")) != "youpassword":
continue用法3:推导式
这个系列的文章,几乎每篇都能看到推导式的身影,这一篇依旧如此。
在编码过程中,我很喜欢使用推导式,在简单的应用场景下,它简洁且不失高效。
如下这段代码中,我会使用列表推导式得出所有会员中过于肥胖的人的 bmi 指数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23members = [
{"name": "小五", "age": 23, "height": 1.75, "weight": 72},
{"name": "小李", "age": 17, "height": 1.72, "weight": 63},
{"name": "小陈", "age": 20, "height": 1.78, "weight": 82},
]
count = 0
def get_bmi(info):
global count
count += 1
print(f"执行了 {count} 次")
height = info["height"]
weight = info["weight"]
return weight / (height**2)
# 查出所有会员中过于肥胖的人的 bmi 指数
fat_bmis = [get_bmi(m) for m in members if get_bmi(m) > 24]
print(fat_bmis)输出如下
1
2
3
4
5执行了 1 次
执行了 2 次
执行了 3 次
执行了 4 次
[25.88057063502083]可以看到,会员数只有 3 个,但是 get_bmi 函数却执行了 4 次,原因是在判断时执行了 3 次,而在构造新的列表时又重复执行了一遍。
如果所有会员都是过于肥胖的,那最终将执行 6 次,这种在大量的数据下是比较浪费性能的,因此对于这种结构,我通常会使用传统的for 循环 + if 判断。
1
2
3
4
5
6
7fat_bmis = []
# 查出所有会员中过于肥胖的人的 bmi 指数
for m in members:
bmi = get_bmi(m)
if bmi > 24:
fat_bmis.append(bmi)在有了海象运算符之后,你就可以不用在这种场景下做出妥协。
1
2# 查出所有会员中过于肥胖的人的 bmi 指数
fat_bmis = [bmi for m in members if (bmi := get_bmi(m)) > 24]最终从输出结果可以看出,只执行了 3 次
1
2
3
4执行了 1 次
执行了 2 次
执行了 3 次
[25.88057063502083]
4. 逻辑运算符
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔”与” - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值。 | (a and b) 返回 20。 |
or | x or y | 布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
not | not x | 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
and、or运算规则
- x or y 的值只可能是x或y. x为真就是x, x为假就是y
- x and y 的值只可能是x或y. x为真就是y, x为假就是x
1 | v1 = 0 or 4 and 3 or 7 or 9 and 6 |
逻辑运算符有三个,分别是and
、or
和not
。and
字面意思是“而且”,所以and
运算符会连接两个布尔值,如果两个布尔值都是True
,那么运算的结果就是True
;左右两边的布尔值有一个是False
,最终的运算结果就是False
。相信大家已经想到了,如果and
左边的布尔值是False
,不管右边的布尔值是什么,最终的结果都是False
,所以在做运算的时候右边的值会被跳过(短路处理),这也就意味着在and
运算符左边为False
的情况下,右边的表达式根本不会执行。or
字面意思是“或者”,所以or
运算符也会连接两个布尔值,如果两个布尔值有任意一个是True
,那么最终的结果就是True
。当然,or
运算符也是有短路功能的,在它左边的布尔值为True
的情况下,右边的表达式根本不会执行。not
运算符的后面会跟上一个布尔值,它的作用是得到与该布尔值相反的值,也就是说,后面的布尔值如果是True
运算结果就是False
,而后面的布尔值如果是False
则运算结果就是True
。
1 | """ |
说明:比较运算符的优先级高于赋值运算符,所以
flag0 = 1 == 1
先做1 == 1
产生布尔值True
,再将这个值赋值给变量flag0
。,
进行分隔,输出的内容之间默认以空格分开。
5. 位运算符
运算符 | 含义 | 示例 |
---|---|---|
& |
按位与(AND):参与运算的两个值的两个相应位都为1,则该位的结果为1;否则为0 | x & y |
` | ` | 按位或(OR):参与运算的两个值的两个相应位有一个为1,则该位的结果为1;否则为0 |
~ |
按位翻转/取反(NOT):对数据的每个二进制位取反,即把 1 变为 0 ,把 0 变为 1 | ~x |
^ |
按位异或(XOR):当两个对应的二进制位相异时,结果为1 | x ^ y |
>> |
按位右移 :运算数的各个二进制位全部右移若干位 | x >> 2 |
<< |
按位左移:运算数的各个二进制位全部左移若干位,高位丢弃,地位不补 0 | x << 2 |
6. 成员运算符
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
7. 身份运算符
运算符 | 含义 | 示例 |
---|---|---|
is |
如果对象的引用指向同一片内存,则为 True(引用同一个对象) | x is True |
is not |
如果对象的引用不相同,则为 True(引用不同的对象) | x is not True |
8. 运算符优先级
上述所有运算符优先级从高到低总结:算数运算符 > 位运算符 > 比较运算符 > 身份运算符 > 成员运算符 > 逻辑运算符 > 赋值运算符
。具体如下:
运算符 | 描述 |
---|---|
[] [:] |
下标,切片 |
** |
指数 |
~ + - |
按位取反, 正负号 |
* / % // |
乘,除,模,整除 |
+ - |
加,减 |
>> << |
右移,左移 |
& |
按位与 |
^ ` |
` |
<= < > >= |
小于等于,小于,大于,大于等于 |
== != |
等于,不等于 |
is is not |
身份运算符 |
in not in |
成员运算符 |
not or and |
逻辑运算符 |
= += -= *= /= %= //= **= &= ` |
赋值运算符 |
说明: 在实际开发中,如果搞不清楚运算符的优先级,可以使用加括号来确保运算的执行顺序。
9. 练习
9.1 练习1:
华氏温度转换为摄氏温度。
提示:华氏温度到摄氏温度的转换公式为:C=(F−32)÷1.8C=(F−32)÷1.8。
参考答案:
1 | """ |
说明:在使用
%1.f
是一个占位符,稍后会由一个float
类型的变量值替换掉它。同理,如果字符串中有%d
,后面可以用一个int
类型的变量值替换掉它,而%s
会被字符串的值替换掉。除了这种格式化字符串的方式外,还可以用下面的方式来格式化字符串,其中{f:.1f}
和{c:.1f}
可以先看成是{f}
和{c}
,表示输出时会用变量f
和变量c
的值替换掉这两个占位符,后面的:.1f
表示这是一个浮点数,小数点后保留1位有效数字。
1 print(f'{f:.1f}华氏度 = {c:.1f}摄氏度')
9.2 练习2:
输入圆的半径计算计算周长和面积。
参考答案:
1 | """ |
9.3 练习3:
输入年份判断是不是闰年。
参考答案:
1 | """ |
说明:比较运算符会产生布尔值,而逻辑运算符
and
和or
会对这些布尔值进行组合,最终也是得到一个布尔值,闰年输出True
,平年输出False
。
六、格式化输出
格式化输出又叫字符串格式化,使用更便捷的形式实现字符串的拼接。格式化字符串时,Python使用一个字符串作为模板。模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式。Python用一个tuple将多个值传递给模板,每个值对应一个格式符。
格式化占位符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符"%示例
1 | name = '张亚飞' |
1. %
1.1 整数输出
- %o —— oct 八进制
- %d —— dec 十进制
- %x —— hex 十六进制
1 | In [1]: print('%o'%10) |
1.2 浮点数
- %f ——默认保留小数点后面六位有效数字
- %.3f,保留3位小数位
- %e ——默认保留小数点后面六位有效数字,指数形式输出
- %.3e,保留3位小数位,使用科学计数法
- %g ——在保证六位有效数字的前提下,使用小数方式,否则使用科学计数法
- %.3g,保留3位有效数字,使用小数或科学计数法
1 | In [11]: print('%f' % 1.11) # 默认保留6位小数 |
1.3 字符串输出
- %s
- %10s——右对齐,占位符10位
- %-10s——左对齐,占位符10位
- %.2s——截取2位字符串
- %10.2s——10位占位符,截取两位字符串
1 | In [18]: print('%s' % 'hello world') # 字符串输出 |
1.4 示例
1 | # 格式的字符串与被格式化的字符串必须一一对应,需格式化的字符串多时,容易搞混 |
2. format
2.1 使用位置参数
1 | print('我叫{0},我的年龄是{1},我是一名{2},我的爱好是{3}'.format(name, age, job, hobby)) |
2.2 字典格式化
1 | print('我叫{name},我的年龄是{age},我是一名{job},我的爱好是{hobby}'.format(name=name, age=age, job=job, hobby=hobby)) |
2.3 填充与格式化
1 | print('{0:*<10}'.format('张亚飞')) |
2.4 精度与进制
1 | print('{0:.2f}'.format(1232132.12321)) #精确到小数点后两位 |
3. f-string
到Python3.6版本,更便捷。
1 | print(f'我叫{name},我的年龄是{age},我是一名{job},我的爱好是{hobby}') |
如果需要进一步控制格式化语法中变量值的形式,可以参照下面的表格来进行字符串格式化操作。
变量值 | 占位符 | 格式化结果 | 说明 |
---|---|---|---|
3.1415926 |
{:.2f} |
'3.14' |
保留小数点后两位 |
3.1415926 |
{:+.2f} |
'+3.14' |
带符号保留小数点后两位 |
-1 |
{:+.2f} |
'-1.00' |
带符号保留小数点后两位 |
3.1415926 |
{:.0f} |
'3' |
不带小数 |
123 |
{:0>10d} |
0000000123 |
左边补0 ,补够10位 |
123 |
{:x<10d} |
123xxxxxxx |
右边补x ,补够10位 |
123 |
{:>10d} |
' 123' |
左边补空格,补够10位 |
123 |
{:<10d} |
'123 ' |
右边补空格,补够10位 |
123456789 |
{:,} |
'123,456,789' |
逗号分隔格式 |
0.123 |
{:.2%} |
'12.30%' |
百分比格式 |
123456789 |
{:.2e} |
'1.23e+08' |
科学计数法格式 |
4. 模板字符串
来看一个例子
1 | from string import Template |
你可以看到我们需要先从Python的内建 string 模块中导入 Template 类。模板字符串并不是核心的语言特征,但是它们由Python标准库的string提供的。
1 | from string import Template |
但是该什么时候才在你的代码中使用模板字符串呢?
其他一些复杂的字符串格式化技巧的可能会给你的程序带来安全漏洞,例如,格式化字符串可以访问你程序里任意的变量。这意味着,如果一个恶意用户可以提供一个格式化字符串,他们就有可能泄露安全密匙以及其他敏感的信息!下面是一个简单的例子证明这些可能可以用来影响你的代码:
1 | """ format安全漏洞 """ |
5. 应用场景
Python字符串格式化经验法则:如果你的格式化字符串是由用户提供的,那么就是用模板字符串(#4)避免安全问题。不然如果是Python 3.6+的话,就使用字符串插值/f-Strings,如果不是就使用“新式”字符串格式化(str.format)。