C中文网python编程基础chapter-3-Python变量类型和运算符

2019-09-04

在C语言中文网上,学习了python编程的基础课程,此为学习笔记记录,备查,备翻阅复习。

变量及类型

Python 是一门弱类型语言,弱类型包含两方面的含义:

  • 所有的变量无须声明即可使用,或者说对从未用过的变量赋值就是声明了应变量;
  • 变量的数据类型可以随时改变,同一个变量可以一会儿是数值型,一会儿是字符串型。
    #定义一个数值类型变量
    a = 5
    print(a)
    #重新将字符串赋值给a变量
    a = 'Hello , Charlie'
    print(a)
    print(type(a))
    

    数值类型(整形、浮点型和复数)及其用法

    Python 中的数值类型主要包括整形、浮点型和复数类型。 整型 在 Python 中,整形专门用来表示整数,整数包括正整数、0 和负整数。 Python 的整型数值有 4 种表示形式: 十进制形式、二进制形式、八进制形式、十六进制形式。 Python 的整型还支持 None 值(空值),例如如下代码:

a = None
print(a) #什么都不输出

#以0x或0X开头的整型数值是十六进制形式的整数
hex_value1 = 0x13
hex_value2 = 0xaF
print("hexValue1 的值为:",hex_value1)
print("hexValue2 的值为:",hex_value2)
#以0b或0B开头的整型数值是二进制形式的整数
bin_val = 0b111
print('bin_val的值为:',bin_val)
bin_val = 0B101
print('bin_val的值为:',bin_val)
#以0o或0O开头的整型数值是八进制形式的整数
oct_val = 0o54
print('oct_val 的值为:',oct_val)
oct_val = 0O17
print('oct_val 的值为:',oct_val)

浮点型 浮点型数值用于保存带小数点的数值,Python 的浮点数有两种表示形式:

  • 十进制形式:这种形式就是平常简单的浮点数,例如 5.12、512.0、0.512。浮点数必须包含一个小数点,否则会被当成整数类型处理。
  • 科学计数形式:例如 5.12e2(即 5.12×102)、5.12E2(也是 5.12 ×102)。

只有浮点型数值才可以使用科学计数形式表示。例如 51200 是一个整型值,但 512E2 则是浮点型值。也就是说python自动会将512E2转化为51200.0,就是浮点型的变量。

为了提高数值(包括浮点型)的可读性,Python 3.x 允许为数值(包括浮点型)增加下画线作为数字的分隔符。这些下画线并不会影响数值本身。例如如下代码:

#在数值中使用下画线
one_million = 1000000
print(one_million)
price = 234_234_234 #price 实际的值为234234234
android = 12341234 #android 实际的值为12341234

复数

Python 可以支持复数,复数的虚部用 j 或 J 来表示。不常用,可以暂不了解。

如果需要在程序中对复数进行计算,可导入 Python 的 cmath 模块(c 代表 complex),在该模块下包含了各种支持复数运算的函数。

下面程序示范了复数的用法:

ac1 = 3 + 0.2j
print (ac1)
print(type(ac1)) #输出复数类型
ac2 = 4 - 0.1j
print(ac2)
#复数运行
print(ac1 + ac2) #输出(7+0.1j)
#导入cmath 模块
import cmath
#sqrt()是cmath 模块下的商数,用于计算平方根
ac3 = cmath.sqrt(-1)
print (ac3) #输出1j

字符串详解

Python 要求,字符串必须使用引号括起来,可以使用单引号或者双引号,只要成对即可。

如果字符串内容本身包含了单引号或双引号,此时就需要进行特殊处理:

#  1. 使用不同的引号将字符串括起来。
str3 = "I'm a coder"
str4 = '"Spring is here,let us jam!", said woodchuck.'

#  2. 对引号进行转义。
# 使用反斜线(\)将字符串中的特殊字符进行转义
 str5 = '"we are scared,Let\'s hide in the shade",says the bird'

长字符串

使用三个引号定义长字符串,该长字符串中既可包含单引号,也可包含双引号。

s = '''"Let's go fishing", said Mary.
"OK, Let's go", said her brother.
they walked to a lake'''
print(s)

如果所定义的长字符串没有赋值给任何变量,那么这个字符串就相当于被解释器忽略了,也就是多行注释了。

原始字符串

由于字符串中的反斜线都有特殊的作用,因此当字符串中包含反斜线时,就需要使用转义字符 \ 对字符串中包含的每个 ‘' 进行转义。

比如说,我们要写一个关于 Windows 路径 G:\publish\codes\02\2.4 这样的字符串,如果在 Python 程序中直接这样写肯定是不行的,需要使用 \ 转义字符,对字符串中每个 ‘' 进行转义,即写成 G:\publish\codes\02\2.4 这种形式才行。

还有更好的解决办法,就是借助于原始字符串。 原始字符串以“r”开头,它不会把反斜线当成特殊字符。因此,上面的 Windows 路径可直接写成如下这种形式:

s1 = r'G:\publish\codes\02\2.4'
print(s1)

bytes类型及用法

Python 3 新增了 bytes 类型,用于代表字节串(这是本教程创造的一个词,用来和字符串对应)。字符串(str)由多个字符组成,以字符为单位进行操作;字节串(bytes)由多个字节组成,以字节为单位进行操作。

bytes 和 str 除操作的数据单元不同之外,它们支持的所有方法都基本相同,bytes 也是不可变序列。 由于 bytes 保存的就是原始的字节(二进制格式)数据,因此 bytes 对象可用于在网络上传输数据,也可用于存储各种二进制格式的文件,比如图片、音乐等文件。 如下程序示范了如何创建字节串:

# 创建一个空的bytes
b1 = bytes()
# 创建一个空的bytes值
b2 = b''
# 通过b前缀指定hello是bytes类型的值
b3 = b'hello'
print(b3)
print(b3[0])
print(b3[2:4])
# 调用bytes方法将字符串转成bytes对象
b4 = bytes('我爱Python编程',encoding='utf-8')
print(b4)
# 利用字符串的encode()方法编码成bytes,默认使用utf-8字符集
b5 = "学习Python很有趣".encode('utf-8')
print(b5)

运行上面程序,可以看到如下输出结果:

b'hello'
104
b'll'
b'\xe6\x88\x91\xe7\x88\xb1Python\xe7\xbc\x96\xe7\xa8\x8b'
b'\xe5\xad\xa6\xe4\xb9\xa0Python\xe5\xbe\x88\xe6\x9c\x89\xe8\xb6\xa3'

从上面的输出结果可以看出,字节串和字符串非常相似,只是字节串里的每个数据单元都是 1 字节。

bool布尔类型

Python 提供了 bool 类型来表示真(对)或假(错)。

True 和 False 是 Python 中的关键字,当作为 Python 代码输入时,一定要注意字母的大小写,否则解释器会报错。

len()函数详解

Python 中,要想知道一个字符串有多少个字符(获得字符串长度),或者一个字符串占用多少个字节,可以使用 len 函数。

>>> a='http://c.biancheng.net'
>>> len(a)
22

在实际开发中,除了常常要获取字符串的长度外,有时还要获取字符串的字节数。 在 Python 中,不同的字符所占的字节数不同,数字、英文字母、小数点、下划线以及空格,各占一个字节,而一个汉字可能占 2~4 个字节,具体占多少个,取决于采用的编码方式。例如,汉字在 GBK/GB2312 编码中占用 2 个字节,而在 UTF-8 编码中一般占用 3 个字节。

我们可以通过使用** encode()**方法,将字符串进行编码后再获取它的字节数。

# 采用 UTF-8 编码方式,计算“人生苦短,我用Python”的字节数
>>> str1 = "人生苦短,我用Python"
>>> len(str1.encode())
27

# 获取采用 GBK 编码的字符串的长度
>>> str1 = "人生苦短,我用Python"
>>> len(str1.encode('gbk'))
20

input()函数

input() 函数用于向用户生成一条提示,然后获取用户输入的内容。由于 input() 函数总会将用户输入的内容放入字符串中,因此用户可以输入任何内容,input() 函数总是返回一个字符串

msg  input("请输入你的值:")
print (type(msg))
print(msg)

print()函数高级用法

print() 函数的详细语法格式如下:

print (value,...,sep='',end='\n',file=sys.stdout,flush=False)

从上面的语法格式可以看出,value 参数可以接受任意多个变量或值,因此 print() 函数完全可以输出多个值。例如如下代码:

user_name  'Charlie'
user_age = 8
#同时输出多个变量和字符串
print("读者名:",user_name,"年龄:",user_age)

输出结果:

读者名: Charlie 年龄: 8

从输出结果来看,使用 print() 函数输出多个变量时,print() 函数默认以空格隔开多个变量,如果读者希望改变默认的分隔符,可通过 sep 参数进行设置。

#同时输出多个变量和字符串,指定分隔符
print("读者名:" ,user_name,"年龄:",user_age,sep='|')

输出结果:

读者名:|Charlie|年龄:|8

在默认情况下,print() 函数输出之后总会换行,这是因为 print() 函数的 end 参数的默认值是“\n”,这个“\n”就代表了换行。如果希望 print() 函数输出之后不会换行,则重设 end 参数即可,例如如下代码:

#设置end 参数,指定输出之后不再换行
print(40,'\t',end"")
print(5O,'\t',end"")
print(60,'\t',end""

输出结果:

40    50    60

file 参数指定 print() 函数的输出目标,file 参数的默认值为 sys.stdout,该默认值代表了系统标准输出,也就是屏幕,因此print() 函数默认输出到屏幕。实际上,完全可以通过改变该参数让 print() 函数输出到特定文件中,例如如下代码:

f = open("demo.txt","w")#打开文件以便写入
print('沧海月明珠有泪',file=f)
print('蓝回日暖玉生烟',file=f)
f.close()
# open() 函数用于打开 demo.txt 文件,接连 2 个 print 函数会将这 2 段字符串依次写入此文件,最后调用 close() 函数关闭文件

print() 函数的 flush 参数用于控制输出缓存,该参数一般保持为 False 即可,这样可以获得较好的性能。

格式化字符串

Python 提供了“%”对各种类型的数据进行格式化输出,例如如下代码:

price = 108
print ("the book's price is %s" % price)

上面程序中的 print 函数包含以下三个部分,第一部分是格式化字符串(相当于字符串模板),该格式化字符串中包含一个“%s”占位符,它会被第三部分的变量或表达式的值代替;第二部分固定使用“%”作为分隔符。 格式化字符串中的“%s”被称为转换说明符,其作用相当于一个占位符,它会被后面的变量或表达式的值代替。“%s”指定将变量或值使用 str() 函数转换为字符串。

如果格式化字符串中包含多个“%s”占位符,第三部分也应该对应地提供多个变量,并且使用圆括号将这些变量括起来。例如如下代码:

user = "Charli"
age = 8
# 格式化字符串有两个占位符,第三部分提供2个变量
print("%s is a %s years old boy" % (user , age))

表 1 Python转换说明符列表

转换说明符 说明
%d,%i 转换为带符号的十进制形式的整数
%o 转换为带符号的八进制形式的整数
%x,%X 转换为带符号的十六进制形式的整数
%e 转化为科学计数法表示的浮点数(e 小写)
%E 转化为科学计数法表示的浮点数(E 大写)
%f,%F 转化为十进制形式的浮点数
%g 智能选择使用 %f 或 %e 格式
%G 智能选择使用 %F 或 %E 格式
%c 格式化字符及其 ASCII
%r 使用 repr() 将变量或表达式转换为字符串
%s 使用 str() 将变量或表达式转换为字符串

当使用上面的转换说明符时,可指定转换后的最小宽度,例如如下代码:

num = -28
print("num is: %6i" % num)
print("num is: %6d" % num)
print("num is: %6o" % num)
print("num is: %6x" % num)
print("num is: %6X" % num)
print("num is: %6s" % num)

运行上面代码,可以看到如下输出结果:

num is:    -28
num is:    -28
num is:    -34
num is:    -1c
num is:    -1C
num is:    -28

从上面的输出结果可以看出,此时指定了字符串的最小宽度为 6,因此程序转换数值时总宽度为 6,程序自动在数值前面补充了三个空格。

在默认情况下,转换出来的字符串总是右对齐的,不够宽度时左边补充空格。Python 也允许在最小宽度之前添加一个标志来改变这种行为,Python 支持如下标志:

  • -:指定左对齐。
  • +:表示数值总要带着符号(正数带“+”,负数带“-”)。
  • 0:表示不补充空格,而是补充 0。

例如如下代码:

num2 = 30
# 最小宽度为6,左边补0
print("num2 is: %06d" % num2)
# 最小宽度为6,左边补0,总带上符号
print("num2 is: %+06d" % num2)
# 最小宽度为6,右对齐
print("num2 is: %-6d" % num2)

运行上面代码,可以看到如下输出结果:

num2 is: 000030
num2 is: +00030
num2 is: 30

对于转换浮点数,Python 还允许指定小数点后的数字位数:如果转换的是字符串,Python 允许指定转换后的字符串的最大字符数。这个标志被称为精度值,该精度值被放在最小宽度之后,中间用点 (.) 隔开。例如如下代码:

# 指定小数点后的数字位数
my_value = 3.001415926535
# 最小宽度为8,小数点后保留3位
print("my_value is: %8.3f" % my_value)
# 最小宽度为8,小数点后保留3位,左边补0
print("my_value is: %08.3f" % my_value)
# 最小宽度为8,小数点后保留3位,左边补0,始终带符号
print("my_value is: %+08.3f" % my_value)

# 指定转换后的字符串的最大字符数
the_name = "Charlie"
# 只保留3个字符
print("the name is: %.3s" % the_name) # 输出Cha
# 只保留2个字符,最小宽度10
print("the name is: %10.2s" % the_name)

运行上面代码,可以看到如下输出结果:

my_value is:    3.001
my_value is: 0003.001
my_value is: +003.001
    
the name is: Cha
the name is:         Ch

转义字符及高级用法

Python 中常用的转义字符如表 1 所示:

转义字符 说明
\ 在行尾的续行符,即一行未完,转到下一行继续写
' 单引号
" 双引号
\0
\n 换行符
\r 回车符
\t 水平制表符,用于横向跳到下一制表位
\a 响铃
\b 退格(Backspace)
\ 反斜线
\0dd 八进制数,dd 代表字符,如 \012 代表换行
\xhh 十六进制数,hh 代表字符,如 \x0a 代表换行

使用举例:

s = 'Hello\nCharlie\nGood\nMorning'
print(s)
Hello
Charlie
Good
Morning
s2 = '商品名\t\t单价\t\t数量\t\t总价'
s3 = 'C语言小白变怪兽\t99\t\t2\t\t198'
print(s2)
print (s3)
商品名                 单价        数量        总价
C语言小白变怪兽 99           2             198

数据类型转换函数

表 1 常用数据类型转换函数

函 数 作 用
int(x) 将 x 转换成整数类型
Iloat(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 转换为一个八进制的字符串

需要注意的是,在使用类型转换函数时,提供给它的数据必须是有意义的。例如,int() 函数无法将一个非数字字符串转换成整数。

算术运算符及用法

表 1 Python常用算术运算符

运算符 说明 实例 结果
+ 12.45 + 15 27.45
- 4.56 - 0.26 4.3
* 5 * 3.6 18.0
/ 7 / 2 3.5
% 取余,即返回除法的余数 7 % 2 1
// 整除,返回商的整数部分 7 // 2 3
** 幂,即返回 x 的 y 次方 2 ** 4 16,即 24

“+”还可以作为字符串(包括后续要介绍的序列)的连接运算符。

“*”还可以作为字符串(包括后续要介绍的序列)的连接运算符,表示将 N 个字符串连接起来。举例:

s1 = 'Hello, '
s2 = 'Charlie'
# 使用+连接两个字符串
print(s1 + s2)

s3 = 'crazyit '
# 使用*将5个字符串连接起来
print(s3 * 5)

赋值运算符

Python 使用“=”作为赋值运算符。 Python 支持连续赋值,如a = b = c = 20。 表 1 Python 常用赋值运算符

运算符 说 明 举 例 展开形式
= 最基本的赋值运算 x = y x = y
+= 加赋值 x += y x = x + y
-= 减赋值 x -= y x = x - y
*= 乘赋值 x *= y x = x * y
/= 除赋值 x /= y x = x / y
%= 取余数赋值 x %= y x = x % y
**= 幂赋值 x **= y x = x ** y
//= 取整数赋值 x //= y x = x // y
|= 按位或赋值 x |= y x = x | y
^= 按位与赋值 x ^= y x = x ^ y
«= 左移赋值 x «= y x = x « y,这里的 y 指的是左移的位数
»= 右移赋值 x »= y x = x » y,这里的 y 指的是右移的位数

通常情况下,只要能使用扩展后的赋值运算符,都推荐使用这种赋值运算符。

位运算符

位运算符通常在图形、图像处理和创建设备驱动等底层开发中使用。使用位运算符可以直接操作数值的原始 bit 位,尤其是在使用自定义的协议进行通信时,使用位运算符对原始数据进行编码和解码也非常有效。

位运算符对于初学者来说有些难度,因此初学者可先跳过本节内容。

比较运算符

也称关系运算符

表 1 Python 比较运算符

比较运算符 功能
> 大于,如果运算符前面的值大于后面的值,则返回 True;否则返回 False
>= 大于或等于,如果运算符前面的值大于或等于后面的值,则返回 True;否则返回 False
< 小于,如果运算符前面的值小于后面的值,则返回 True;否则返回 False
<= 小于或等于,如果运算符前面的值小于或等于后面的值,则返回 True;否则返回 False
== 等于,如果运算符前面的值等于后面的值,则返回 True;否则返回 False
!= 不等于,如果运算符前面的值不等于后面的值,则返回 True;否则返回 False
is 判断两个变量所引用的对象是否相同,如果相同则返回 True
is not 判断两个变量所引用的对象是否不相同,如果不相同则返回 True

比较运算符 == 和 is 的区别

== 用来比较两个变量的值是否相等,而 is 则用来比对两个变量引用的是否是同一个对象,例如:

import time
# 获取当前时间
a = time.gmtime()
b =  time.gmtime()
print(a == b) # a和b两个时间相等,输出True
print(a is b) # a和b不是同一个对象,输出False

上面代码中 a、b 两个变量都代表当前系统时间,因此 a、b 两个变量的时间值是相等的(代码运行速度很快,能保证是同一时间),故程序使用“==”判断返回 True。但由于 a、b 两个变量分别引用不同的对象(每次调用 gmtime() 函数都返回不同的对象),因此a is b返回 False。

那么,如何判断两个变量是否属于一个对象呢?Python 提供了一个全局的 id() 函数,它可以用来判断变量所引用的对象的内存地址(相当于对象在计算机内存中存储位置的门牌号),如果两个对象所在的内存地址相同(相当于它们住在同一个房间内,计算机同一块内存在任一时刻只能存放一个对象),则说明这两个对象其实是同一个对象。 由此可见,is 判断其实就是要求通过 id() 函数计算两个对象时返回相同的地址。例如,使用 id() 函数判断上面的 a、b 两个变量:

print(id(a))
print(id(b))

从运行结果中将会看到 a、b 两个变量所引用的对象的内存地址是不同的,这样通过 is 来判断 a、b 两个变量自然也就输出 False 了。

>>> a = 'cheesezh'
>>> b = 'cheesezh'
>>> id(a)
2680257978480
>>> id(b)
2680257978480
>>> a is b
True

逻辑运算符

逻辑运算符是对真和假两种布尔值进行运算(操作 bool 类型的变量、常量或表达式),逻辑运算的返回值也是 bool 类型值。

表 1 Python 逻辑运算符及功能

逻辑运算符 含义 基本格式 功能
and 逻辑与(简称“与”) a and b 有 2 个操作数 a 和 b,只有它们都是 True 时,才返回 True,否则返回 False。
or 逻辑或(简称“或”) a or b 有 2 个操作数 a 和 b ,只有它们都是 False 时,才返回 False,否则返回 True。
not 逻辑非(简称“非”) not a 只需要 1 个操作数 a,如果 a 的值为 True,则返回 False;反之,如果 a 的值为 False,则返回 True。

需要说明的是,建议使用圆括号来提高程序的可读性。

三目运算符

作为三目运算符的 if 语句的语法格式如下:

 True_statements if expression else False_statements

三目运算符的规则是:先对逻辑表达式 expression 求值,如果逻辑表达式返回 True,则执行并返回 True_statements 的值;如果逻辑表达式返回 False,则执行并返回 False_statements 的值。看如下代码:

a = 5
b = 3
st = "a大于b" if a > b else  "a不大于b"
# 输出"a大于b"
print(st)

Python 允许在三目运算符的 True_statements 或 False_statements 中放置多条语句。Python 主要支持以下两种放置方式:

  1. 多条语句以英文逗号隔开:每条语句都会执行,程序返回多条语句的返回值组成的元组。
  2. 多条语句以英文分号隔开:每条语句都会执行,程序只返回第一条语句的返回值

举例

# 第一个返回值部分使用两条语句,逗号隔开
st = print("crazyit"), 'a大于b' if a > b else  "a不大于b"
print(st)

上面程序中 True_statements 为 print(“crazyit”),’a大于b’,这两条语句都会执行,程序将会返回这两条语句的返回值组成的元组。由于 print() 函数没有返回值,相当于它的返回值是 None。运行上面代码,将看到如下结果:

crazyit
(None,'a大于b')
# 第一个返回值部分使用两条语句,分号隔开
st = print("crazyit"); x = 20 if a > b else  "a不大于b"
print(st)
print(x)

此时虽然 True_statements 包含两条语句,但程序只会返回第一条语句 print(”crazyit”) 的返回值,该语句同样返回 None,因此相当于 str 的返回值为 None。运行上面代码,将看到如下结果:

crazyit
None
20

三目运算符支持嵌套,通过嵌套三目运算符,可以执行更复杂的判断。例如,下面代码需要判断 c、d 两个变量的大小关系:

c = 5
d = 5
# 下面将输出c等于d
print("c大于d") if c > d else (print("c小于d") if c < d else print("c等于d"))

运算符优先级一览表

运算规则是,优先级高的运算符先执行,优先级低的运算符后执行,同一优先级的运算符按照从左到右的顺序进行。需要注意的是,Python 语言中大部分运算符都是从左向右执行的,只有单目运算符(例如 not 逻辑非运算符)、赋值运算符和三目运算符例外,它们是从右向左执行的。

建议:

  • 不要把一个表达式写得过于复杂,太复杂则分成几步来完成。
  • 应尽量使用“()”来控制表达式的执行顺序。