Python变量类型

变量的赋值

变量的值不是一成不变的,它可以随时被修改,只要重新赋值即可;另外你也不用关心数据的类型,可以将不同类型的数据赋值给同一个变量。

1
2
3
4
5
n = 10  #将10赋值给变量n
n = 95 #将95赋值给变量n
abc = 12.5 #将小数赋值给变量abc
abc = 85 #将整数赋值给变量abc
abc = "hello" #将字符串赋值给变量abc

注意,变量的值一旦被修改,之前的值就被覆盖了,不复存在了,再也找不回了。换句话说,变量只能容纳一个值。

除了赋值单个数据,你也可以将表达式的运行结果赋值给变量:

1
2
sum = 100 + 20  #将加法的结果赋值给变量
rem = 25 * 30 % 7 #将余数赋值给变量

变量的使用

使用 Python 变量时,只要知道变量的名字即可。

1
2
3
4
5
6
7
8
9
n = 10
print(n) #将变量传递给函数
# 10
m = n * 10 + 5 #将变量作为四则运算的一部分
print(m) # 105
print(m - 30) #将由变量构成的表达式作为参数传递给函数
# 75
m = m * 2 #将变量本身的值翻倍
print(m) # 210

Python 是弱类型的语言

在强类型的编程语言中,定义变量时要指明变量的类型,而且赋值的数据也必须是相同类型的。和强类型语言相对应的是弱类型语言,Python、JavaScript、PHP 等脚本语言一般都是弱类型的。

弱类型语言有两个特点:

  • 变量无须声明就可以直接赋值,对一个不存在的变量赋值就相当于定义了一个新变量。
  • 变量的数据类型可以随时改变,比如,同一个变量可以一会儿被赋值为整数,一会儿被赋值为字符串。

注意,弱类型并不等于没有类型!弱类型是说在书写代码时不用刻意关注类型,但是在编程语言的内部仍然是有类型的。我们可以使用type()内置函数类检测某个变量或者表达式的类型:

1
2
3
4
5
6
7
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'>

整数类型(int)

整数就是没有小数部分的数字,Python 中的整数包括正整数、0 和负整数。

Python 的整数不分类型,或者说它只有一种类型的整数。Python 整数的取值范围是无限的。

当所用数值超过计算机自身的计算能力时,Python 会自动转用高精度计算(大数计算)。

1
2
3
4
5
6
7
8
9
10
11
12
#将 78 赋值给变量 n
n = 78
print(n) # 78
print(type(n)) # <class 'int'>
#给x赋值一个很大的整数
x = 8888888888888888888888
print(x) # 8888888888888888888888
print(type(x)) # <class 'int'>
#给y赋值一个很小的整数
y = -7777777777777777777777
print(y) # -7777777777777777777777
print(type(y)) # <class 'int'>

不管对于多大或者多小的整数,Python 只用一种类型存储,就是int

整数的不同进制

可以使用多种进制来表示整数:

  1. 十进制形式:由 0~9 共十个数字排列组合而成。
  2. 二进制形式:由 0 和 1 两个数字组成,书写时以0b0B开头。例如,101 对应十进制数是 5。
  3. 八进制形式:八进制整数由 0~7 共八个数字组成,以0o0O开头。注意,第一个符号是数字 0,第二个符号是大写或小写的字母O
  4. 十六进制形式:由 09 十个数字以及 AF(或 a~f)六个字母组成,书写时以0x0X开头,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#十六进制
hex1 = 0x45
hex2 = 0x4Af
print("hex1Value: ", hex1) # hex1Value: 69
print("hex2Value: ", hex2) # hex2Value: 1199
#二进制
bin1 = 0b101
print('bin1Value: ', bin1) # bin1Value: 5
bin2 = 0B110
print('bin2Value: ', bin2) # bin2Value: 6
#八进制
oct1 = 0o26
print('oct1Value: ', oct1) # oct1Value: 22
oct2 = 0O41
print('oct2Value: ', oct2) # oct2Value: 33

数字分隔符

为了提高数字的的可读性,Python 3.x 允许使用下划线_作为数字(包括整数和小数)的分隔符。通常每隔三个数字添加一个下划线,类似于英文数字中的逗号。下划线不会影响数字本身的值。

1
2
distance = 384_000_000
print("地球和月球的距离:", distance) # 地球和月球的距离:384000000

小数/浮点数(float)

小数通常以浮点数的形式存储。浮点数和定点数是相对的:小数在存储过程中如果小数点发生移动,就称为浮点数;如果小数点不动,就称为定点数。

Python 中的小数有两种书写形式:

  1. 十进制形式:例如 34.6、346.0、0.346。书写小数时必须包含一个小数点,否则会被当作整数处理。
  2. 指数形式:小数的指数形式的写法为:aEnaena为尾数部分,是一个十进制数;n为指数部分,是一个十进制整数;Ee是固定的字符,用于分割尾数部分和指数部分。整个表达式等价于 a×10n

指数形式的小数举例:

  • 2.1E5 = 2.1×105,其中 2.1 是尾数,5 是指数。
  • 3.7E-2 = 3.7×10-2,其中 3.7 是尾数,-2 是指数。
  • 0.5E7 = 0.5×107,其中 0.5 是尾数,7 是指数。

注意,只要写成指数形式就是小数,即使它的最终值看起来像一个整数。例如14E3等价于 14000,但 14E3 是一个小数。

Python 只有一种小数类型,就是float

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
f1 = 12.5
print("f1Value: ", f1) # f1Value: 12.5
print("f1Type: ", type(f1)) # f1Type: <class 'float'>
f2 = 0.34557808421257003
print("f2Value: ", f2) # f2Value: 0.34557808421257
print("f2Type: ", type(f2)) # f2Type: <class 'float'>
f3 = 0.0000000000000000000000000847
print("f3Value: ", f3) # f3Value: 8.47e-26
print("f3Type: ", type(f3)) # f3Type: <class 'float'>
f4 = 345679745132456787324523453.45006
print("f4Value: ", f4) # f4Value: 3.456797451324568e+26
print("f4Type: ", type(f4)) # f4Type: <class 'float'>
f5 = 12e4
print("f5Value: ", f5) # f5Value: 120000.0
print("f5Type: ", type(f5)) # f5Type: <class 'float'>
f6 = 12.3 * 0.1
print("f6Value: ", f6) # f6Value: 1.2300000000000002
print("f6Type: ", type(f6)) # f6Type: <class 'float'>

从运行结果可以看出,Python 能容纳极小和极大的浮点数。print在输出浮点数时,会根据浮点数的长度和大小适当的舍去一部分数字,或者采用科学计数法。

f5的值是 120000,但是它依然是小数类型,而不是整数类型。

f612.3*0.1的计算结果很明显是 1.23,但是print的输出却不精确。这是因为小数在内存中是以二进制形式存储的,小数点后面的部分在转换成二进制时很有可能是一串无限循环的数字,无论如何都不能精确表示,所以小数的计算结果一般都是不精确的。

字符串

若干个字符的集合就是一个字符串(String)。字符串必须由双引号" "或者单引号' '包围:

1
2
"字符串内容"
'字符串内容'

字符串中的双引号和单引号没有任何区别。

处理字符串中的引号的

当字符串内容中出现引号时,我们需要进行特殊处理,否则 Python 会解析出错:

1
'I'm a great coder!'

由于上面字符串中包含了单引号,此时 Python 会将字符串中的单引号与第一个单引号配对,这样就会把'I'当成字符串,而后面的m a great coder!'就变成了多余的内容,从而导致语法错误。

对于这种情况,我们有两种处理方案:

1.对引号进行转义

在引号前面添加反斜杠\就可以对引号进行转义,让 Python 把它作为普通文本对待:

1
2
3
4
str1 = 'I\'m a great coder!'
str2 = "引文双引号是\",中文双引号是“"
print(str1) # I'm a great coder!
print(str2) # 引文双引号是",中文双引号是“

2.使用不同的引号包围字符串

如果字符串内容中出现了单引号,那么我们可以使用双引号包围字符串,反之亦然。

1
2
str1 = "I'm a great coder!"  #使用双引号包围含有单引号的字符串
str2 = '引文双引号是",中文双引号是“' #使用单引号包围含有双引号的字符串

字符串的换行

Python 不是格式自由的语言,它对程序的换行、缩进都有严格的语法要求。要想换行书写一个比较长的字符串,必须在行尾添加反斜杠\

1
2
3
s2 = 'It took me six months to write this Python tutorial. \
Please give me more support. \
I will keep it updated.'

Python 也支持表达式的换行:

1
2
3
num = 20 + 3 / 4 + \
2 * 3
print(num)

长字符串

使用三个单引号或者双引号可以对多行内容进行注释,这其实是 Python 长字符串的写法。所谓长字符串,就是可以直接换行(不用加反斜杠\)书写的字符串。

长字符串由三个双引号"""或者三个单引号'''包围:

1
2
"""长字符串内容"""
'''长字符串内容'''

在长字符串中放置单引号或者双引号不会导致解析错误。

如果长字符串没有赋值给任何变量,那么这个长字符串就不会起到任何作用,和一段普通的文本无异,相当于被注释掉了。

注意,此时 Python 解释器并不会忽略长字符串,也会按照语法解析,只是长字符串起不到实际作用而已。

当程序中有大段文本内容需要定义成字符串时,优先推荐使用长字符串形式,因为这种形式非常强大,可以在字符串中放置任何内容,包括单引号和双引号。

1
2
3
longstr = '''It took me 6 months to write this Python tutorial.
Please give me a to 'thumb' to keep it updated.'''
print(longstr)

长字符串中的换行、空格、缩进等空白符都会原样输出。

Python原始字符串

Python 字符串中的反斜杠\有着特殊的作用,就是转义字符。

转义字符有时候会带来一些麻烦,例如我要表示一个包含 Windows 路径D:\Program Files\Python 3.8\python.exe这样的字符串,在 Python 程序中直接这样写肯定是不行的,不管是普通字符串还是长字符串。因为\的特殊性,我们需要对字符串中的每个\都进行转义,也就是写成D:\\Program Files\\Python 3.8\\python.exe这种形式才行。

为了解决转义字符的问题,Python 支持原始字符串。在原始字符串中,\不会被当作转义字符,所有的内容都保持“原汁原味”的样子。

在普通字符串或者长字符串的开头加上r前缀,就变成了原始字符串:

1
2
str1 = r'原始字符串内容'
str2 = r"""原始字符串内容"""

将上面的 Windows 路径改写成原始字符串的形式:

1
2
rstr = r'D:\Program Files\Python 3.8\python.exe'
print(rstr)

原始字符串中的引号

如果普通格式的原始字符串中出现引号,程序同样需要对引号进行转义,否则 Python 照样无法对字符串的引号精确配对;但是和普通字符串不同的是,此时用于转义的反斜杠会变成字符串内容的一部分。

1
2
str1 = r'I\'m a great coder!'
print(str1) # I\'m a great coder!

需要注意的是,Python 原始字符串中的反斜杠仍然会对引号进行转义,因此原始字符串的结尾处不能是反斜杠,否则字符串结尾处的引号会被转义,导致字符串不能正确结束。

在 Python 中有两种方式解决这个问题:一种方式是改用长字符串的写法,不要使用原始字符串;另一种方式是单独书写反斜杠。

例如想表示D:\Program Files\Python 3.8\,可以这样写:

1
2
str1 = r'D:\Program Files\Python 3.8' '\\'
print(str1) # D:\Program Files\Python 3.8\

我们先写了一个原始字符串r'D:\Program Files\Python 3.8',紧接着又使用'\\'写了一个包含转义字符的普通字符串,Python 会自动将这两个字符串拼接在一起。

bytes类型

bytes类型用来表示一个字节串。

字节串(bytes)和字符串(string)的对比:

  • 字符串由若干个字符组成,以字符为单位进行操作;字节串由若干个字节组成,以字节为单位进行操作。
  • 字节串和字符串除了操作的数据单元不同之外,它们支持的所有方法都基本相同。
  • 字节串和字符串都是不可变序列,不能随意增加和删除数据。

bytes只负责以字节序列的形式(二进制形式)来存储数据,至于这些数据到底表示什么内容(字符串、数字、图片、音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),字节串可以恢复成字符串;反之亦然,字符串也可以转换成字节串。

我们可以通过字符串来创建bytes对象,或者说将字符串转换成bytes对象。有以下三种方法可以达到这个目的:

  • 如果字符串的内容都是 ASCII 字符,那么直接在字符串前面添加b前缀就可以转换成bytes
  • bytes是一个类,调用它的构造方法,也就是bytes(),可以将字符串按照指定的字符集转换成bytes;如果不指定字符集,那么默认采用 UTF-8。
  • 字符串本身有一个encode()方法,该方法专门用来将字符串按照指定的字符集转换成对应的字节串;如果不指定字符集,那么默认采用 UTF-8。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#通过构造函数创建空 bytes
b1 = bytes()
#通过空字符串创建空 bytes
b2 = b''
#通过b前缀将字符串转换成 bytes
b3 = b'python'
print("b3: ", b3) # b3: b'python'
print(b3[3]) # 112
print(b3[7:22])
#为 bytes() 方法指定字符集
b4 = bytes('小明8岁了', encoding='UTF-8')
print("b4: ", b4)
#通过 encode() 方法将字符串转换成 bytes
b5 = "小明8岁了".encode('UTF-8')
print("b5: ", b5)

从运行结果可以发现,对于非 ASCII 字符,print输出的是它的字符编码值(十六进制形式),而不是字符本身。非 ASCII 字符一般占用两个字节以上的内存,而bytes是按照单个字节来处理数据的,所以不能一次处理多个字节。

bytes类也有一个decode()方法,通过该方法可以将bytes对象转换为字符串。

1
2
3
#通过 decode() 方法将 bytes 转换成字符串
str1 = b5.decode('UTF-8')
print("str1: ", str1)

bool布尔类型

bool类型表示真(对)或假(错)。TrueFalse是 Python 中的关键字,当作为 Python 代码输入时,一定要注意字母的大小写,否则解释器会报错。

布尔类型可以当做整数来对待,即True相当于整数值 1,False相当于整数值 0。因此,下边这些运算都是可以的:

1
2
3
4
False+1
1
True+1
2
1
2
3
4
5>3
True
4>20
False

在 Python 中,所有的对象都可以进行真假值的测试,包括字符串、元组、列表、字典、对象等。

input()函数

input()是 Python 的内置函数,用于从控制台读取用户输入的内容。input()函数总是以字符串的形式来处理用户输入的内容,所以用户输入的内容可以包含任何字符。

1
str = input(tipmsg)

说明:

  • str表示一个字符串类型的变量,input会将读取到的字符串放入str中。
  • tipmsg表示提示信息,它会显示在控制台上,告诉用户应该输入什么样的内容;如果不写tipmsg,就不会有任何提示信息。
1
2
3
4
5
6
7
a = input("Enter a number: ")
b = input("Enter another number: ")
print("aType: ", type(a))
print("bType: ", type(b))
result = a + b
print("resultValue: ", result)
print("resultType: ", type(result))

运行结果:

1
2
3
4
5
6
Enter a number: 100↙
Enter another number: 45↙
aType: <class 'str'>
bType: <class 'str'>
resultValue: 10045
resultType: <class 'str'>

↙表示按下回车键,按下回车键后input()读取就结束了。

本例中我们输入了两个整数,希望计算出它们的和,但是事与愿违,Python 只是它们当成了字符串,+起到了拼接字符串的作用,而不是求和的作用。

我们可以使用 Python 内置函数将字符串转换成想要的类型:

  • int(string)将字符串转换成int类型;
  • float(string)将字符串转换成float类型;
  • bool(string)将字符串转换成bool类型。

修改上面的代码,将用户输入的内容转换成数字:

1
2
3
4
5
6
7
8
9
a = input("Enter a number: ")
b = input("Enter another number: ")
a = float(a)
b = int(b)
print("aType: ", type(a))
print("bType: ", type(b))
result = a + b
print("resultValue: ", result)
print("resultType: ", type(result))

运行结果:

1
2
3
4
5
6
Enter a number: 12.5↙
Enter another number: 64↙
aType: <class 'float'>
bType: <class 'int'>
resultValue: 76.5
resultType: <class 'float'>

print()函数

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

value参数可以接受任意多个变量或值,因此print()函数完全可以输出多个值。

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

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

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

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

1
2
3
4
#设置end 参数,指定输出之后不再换行
print(40,'\t',end="")
print(50,'\t',end="")
print(60,'\t',end="")

输出结果:

1
40    50    60

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

1
2
3
4
f = open("demo.txt","w")#打开文件以便写入
print('沧海月明珠有泪',file=f)
print('蓝田日暖玉生烟',file=f)
f.close()

上面程序中,open()函数用于打开demo.txt文件,接连 2 个print函数会将这 2 段字符串依次写入此文件,最后调用close()函数关闭文件。

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

格式化字符串

print()函数使用以%开头的转换说明符对各种类型的数据进行格式化输出。

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

转换说明符只是一个占位符,它会被后面表达式(变量、常量、数字、字符串、加减乘除等各种形式)的值代替。

1
2
age = 8
print("小明已经%d岁了!" % age) # 小明已经8岁了!

print()函数中,由引号包围的是格式化字符串,它相当于一个字符串模板,可以放置一些转换说明符(占位符)。本例的格式化字符串中包含一个%d说明符,它最终会被后面的age变量的值所替代。

中间的%是一个分隔符,它前面是格式化字符串,后面是要输出的表达式。

当然,格式化字符串中也可以包含多个转换说明符,这个时候也得提供多个表达式,用以替换对应的转换说明符;多个表达式必须使用小括号( )包围起来。

1
2
3
name = "小明"
age = 8
print("%s已经%d岁了。" % (name, age)) # 小明已经8岁了。

总之,有几个占位符,后面就得跟着几个表达式。

指定最小输出宽度

当使用转换说明符时,可以使用下面的格式指定最小输出宽度(至少占用多少个字符的位置):

  • %10d表示输出的整数宽度至少为 10;
  • %20s表示输出的字符串宽度至少为 20。
1
2
3
4
5
6
7
8
9
10
11
n = 1234567
print("n(10):%10d." % n)
print("n(5):%5d." % n)
url = "python"
print("url(35):%35s." % url)
print("url(20):%20s." % url)
运行结果:
n(10): 1234567.
n(5):1234567.
url(35): python.
url(20): python.

从运行结果可以发现,对于整数和字符串,当数据的实际宽度小于指定宽度时,会在左侧以空格补齐;当数据的实际宽度大于指定宽度时,会按照数据的实际宽度输出。

这里指定的只是最小宽度,当数据的实际宽度足够时,指定的宽度就没有实际意义了。

指定对齐方式

默认情况下,print()输出的数据总是右对齐的。也就是说,当数据不够宽时,数据总是靠右边输出,而在左边补充空格以达到指定的宽度。Python 允许在最小宽度之前增加一个标志来改变对齐方式:

标志 说明
- 指定左对齐
+ 表示输出的数字总要带着符号;正数带 +,负数带 -
0 表示宽度不足时补充 0,而不是补充空格

几点说明:

  • 对于整数,指定左对齐时,在右边补 0 是没有效果的,因为这样会改变整数的值。
  • 对于小数,以上三个标志可以同时存在。
  • 对于字符串,只能使用-标志,因为符号对于字符串没有意义,而补 0 会改变字符串的值。
1
2
3
4
5
6
7
8
9
10
11
n = 123456
# %09d 表示最小宽度为9,左边补0
print("n(09):%09d" % n) # n(09):000123456
# %+9d 表示最小宽度为9,带上符号
print("n(+9):%+9d" % n) # n(+9): +123456
f = 140.5
# %-+010f 表示最小宽度为10,左对齐,带上符号
print("f(-+0):%-+010f" % f) # f(-+0):+140.500000
s = "Hello"
# %-10s 表示最小宽度为10,左对齐
print("s(-10):%-10s." % s) # s(-10):Hello .

指定小数精度

对于小数(浮点数),print()还允许指定小数点后的数字位数,也即指定小数的输出精度。

精度值需要放在最小宽度之后,中间用点号.隔开;也可以不写最小宽度,只写精度。

1
2
%m.nf
%.nf

m表示最小宽度,n表示输出精度,.是必须存在的。

1
2
3
4
5
6
7
f = 3.141592653
# 最小宽度为8,小数点后保留3位
print("%8.3f" % f) # 3.142
# 最小宽度为8,小数点后保留3位,左边补0
print("%08.3f" % f) # 0003.142
# 最小宽度为8,小数点后保留3位,左边补0,带符号
print("%+08.3f" % f) # +003.142

类型转换

常用数据类型转换函数:

函 数 作 用
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 转换为一个八进制的字符串
打赏
  • Copyrights © 2017-2023 WSQ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信