阅读本文大概需要 10 分钟
前言
语言是人类最重要的交际工具,世界上有成千上万种语言,至今无法统计出具体的数字,但无论怎样,本质上语言所起到的作用,就是将人类想要表达意思,通过某种 双方可以理解的语法翻译出来。而计算机语言也是如此,本质上就是一种翻译语言。
英语之所以能成为世界通用语言,抛开西方资本扩张时期,全球范围内建立殖民地以外,其很大一部分原因是因为它简单,不需要复杂的语法,人们很快就能学会。
这点可能会有人反驳:英语能这么流行还不是因为在那个时期,殖民者强迫人们去说英语。学过一点历史的人知道,当年成吉思汗横扫全球,版图横跨欧亚非。照你这么说,现在全世界都应该说中国话,都按中国人的习惯来,现在老外见面打招呼应该是 ”可吃饭了?“,你见过?
而 Python 恰巧在计算机语言中就是一门简单的语言。
Python 中的数据类型
任何一门语言,都是由最基本的数据来构成的,而 Python 中的数据类型分为两类——固定类型,可变类型。这里只讲固定类型。
标识符与关键字
在了解固定类型之前,我们得先知道一些变量的命名规则和一些约定。
创建一个数据时,我们要么将其赋值于一个变量(对象引用),要么直接引用( Python 中进行赋值操作时,其实就是一个对象引用对内存中存放数据的对象进行引用)。而为这个对象引用赋予的名称就叫做标识符,也就是人口相传的变量。
Python 的标识符命名必须符合两条规则,并遵循某些约定。
1. 两条规则
<1> 变量必须由字母,数字,下划线' _ '
组成,且开头必须是字母或下划线
<2> 变量不能与关键字重名。
2. 约定
<1> 不要使用 Python 中已经预定义的标识符。
<2> 避免使用开头和结尾都使用' _ '
(下划线)的命名方式。
Python 中所有关键字
>>> 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']
固定类型
固定类型也叫不可变类型,即已经在内存中存放的数据,只能引用,无法修改。
在一些函数中,你可能会看到函数修改了数据的假象,如
>>> num = 10
>>> def change():
... num = 100
... print('num = %d'%num)
...
>>> change()
num = 100
看似修改了num
的值,其实并没有!
>>> num = 10
>>> def change():
... num = 100
... print('num = %d'%num)
...
>>> change()
num = 100
>>> num
10
可以看到num
的值并没有被修改!
如果你看了上一篇文章,可以很容易就发现其中涉及到的 ‘全局变量’ 和 ‘局部变量’ 问题,其实就是对象引用问题。这个后面会单独写一篇文章说明。
Python 怎么实现对象不可变呢?
在 Python 中只要对象是可哈希的,那么它就是不可变对象。相反,则是可变对象。
那么哈希又是什么呢?
实际上这里的哈希,是一个函数hash()
,它只能对唯一确定的’数’进行运算,并返回一个绝对不相同的数,而对象的id
正好符合这一性质,它会根据给定的对象的id
,返回一个唯一的hash
值。
>>> a = 100
>>> hash(a)
100
而 Python 中所有对象自身都有一个__hash__
方法,该方法会算出自身id
的hash
值。
>>> a = 100
>>> a.__hash__()
100
通过比较对对象使用hash()
函数计算出来的hash
值,和对象自身__hash__
方法计算出来的hash
值,来确定是否是同一个对象,也就是固定类型里面的不可变对象。
而由于可变类型里的对象的id
是不断变化的,故没法进行hash
运算,它们叫做可变对象。
>>> b = [1,2]
>>> id(b)
46772808
>>> id([1,2])
46771976
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
并且HASH
在计算同一个值时,所得到的hash
值是相同的!
又因为所有尝试通过调用不可变对象的 ‘方法’,或函数,来改变不可变对象的值,其返回的都是一个新的对象,原对象并没有被改变。这样实现了不可变对象永远不可变!
了解了固定类型的本质后,就可以介绍有哪几种数据类型是固定类型了。
固定类型只有 5 种,整型 int
,浮点型 float
,字符型 str
,元组 tuple
,和集合里的 forzenset
。
常用的是前四种,介于字符串涉及的内容很多,决定和元组一起放到下一篇。
1. 整型-int
整数的大小仅取决于机器的内存大小,也就是说没有所谓无穷大概念,没有 99999 后面跟着无穷无尽个 9999 这种说法,当你的内存很小时,你要取一个 99 的 n 次方,计算机就会返回一个 MerryError ,告诉你:你想多了。。。整数默认采用十进制。
<1> 整型计算
常用数学函数与操作符都可用于整型,如加减乘( +,—,\*
),
>>> a = 100
>>> b = 200
>>> a + b
300
计算机里的除法其实并不是简单的数学除法,它根据数学除法的定义,将除法分为两个部分,普通意义上的除法/
,和取模%
,即取余数。
>>> a = 8
>>> b = 5
>>> a / b
1.6
>>> a % b
3
需要注意的是 Python 中的除法,返回的并不是一个整型,而是一个浮点型。
>>> a = 2
>>> b = 1
>>> a / b
2.0
如果一定要在除法运算中,得到一个整型,可以通过截除运算//
,舍弃小数部分,向下取整
>>> a = -3
>>> b = 2
>>> a // b # 结果应该是 -1.5,但由于截除运算是向下取整,故为 -2
-2
<2> 整型转换
在进行赋值运算过程中,经常会遇到需要将某个其他类型的对象转换成整型的情况,如l = int('1')
,就是将一个字符型的'1'
转换成整型1
。这种情况称为数据类型转换。
在数据类型转换当中,一般有三种情况:
Ⅰ. 数据类型函数没有参数时,如 i = int()
>>> i = int()
>>> i
0
>>> type(i)
<class 'int'>
这里会返回一个默认值 0,所有数据类型函数如 float(),str()等,都可以不带参数进行调用。
Ⅱ. 数据类型函数含有参数时,当参数类型和数据类型函数一致时,如
>>> i = int(2)
>>> i
2
>>> type(i)
<class 'int'>
# 这里会将`int`类型的对象`2` 赋值给 i。
# 实际上是创建了一个新对象,新对象是原始对象的浅拷贝,暂且不说。
当参数类型与数据类型函数不一致时,此时会尝试数据转换,如
>>> i = '2'
>>> type(i)
<class 'str'>
>>> j = int(i)
>>> j
2
>>> type(j)
<class 'int'>
当参数支持给定的数据类型转换,但转换失败,会返回一个 ValueError
异常,如
>>> i = int('')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''
当参数不支持给定的数据类型转换,会返回一个 TyprError
异常,如
i = int([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
Ⅲ. 数据类型函数含有两个或多个参数时(并不是所有数据类型函数都支持),如
>>> i = int('100',2)
>>> i
4
>>> type(2)
<class 'int'>
# 意思是将 2 进制下的 '100' 转换为整型 4,整型默认为 10 进制。
常用的整数计算
语法 | 意义 |
---|---|
x | y | 表示将 x 和 y 转换成 2 进制并进行或位运算,如 `2 |
x & y | 表示将 x 和 y 转换成 2 进制并进行与位运算,如 2 & 3 ,其结果为 2 |
x ^ y | 表示将 x 和 y 转换成 2 进制并进行异或位运算,如 2 ^ 3 ,其结果为 1 |
x << y | 表示将 x 转换成 2 进制并向左移动 y 位(即在后面补 0),如 2 << 3 ,其结果为 16 |
x >> y | 表示将 x 转换成 2 进制并向右移动 y 位(即在前面补 0),如 2 >> 3 ,其结果为 0 |
~ 2 | 表示将 x 转换成 2 进制并对每一位进行取反操作(即 1 变为 0 ,0 变成 1),如 ~ 2 ,其结果为 1 |
abs(x) | 表示取 x 的绝对值,如 abs(-2) ,其结果为 2 |
divmod(x,y) | 表示以二元祖的形式返回 x / y 所得的商和余数(返回的是两个整型),如 divmod(5,2) ,其结果为 (2,1) |
pow(x,y) | 表示取 x 的 y 次幂,如 pow(2,3) ,其结果为 8 |
x ** y | 表示 x 的 y 次幂,等同于 pow(x,y) ,如 2 ** 2 ,其结果为 4 |
pow(x,y,z) | 表示 (x ** y) % 2,如 pow(2,3,3) ,其结果为 2 |
<2> 浮点型-float
Python 提供三种浮点型,内置的float
,complex
和标准库里面的decimal.Decimal
,浮点值的精度范围取决于构建 Python 的C
(或C#
或Java
)编译器,计算机总是将浮点值以近似值存储!
所有语言在表示浮点数时都存在精确度问题,所以当对两个浮点数进行相等性比较时,并不可靠。
>>> 666e-666 is 0.0
True
# 这里的 e 表示幂,也就是 666 的 -666 次方。
在整型转换中总是返回整数部分,而舍弃小数部分,但有的时候我们需要对小数部分进行操作,即对浮点值进行相关操作。
常用的浮点型操作函数
语法 | 意义 |
---|---|
round(x,y) | 表示将浮点值 x 的小数部分四舍五入,并保留 y 位小数。如 round(2.756,2) ,其返回的值为 2.77 ,默认返回整型 |
ceil(x) | 表示将浮点值 x 向上转化,返回的是整型。如from math import ceil ceil(2.4) ,其返回值为3 |
floor(x) | 表示将浮点值 x 向下转化,返回的是整型,如from math import ceil floor(2.4) ,其返回值为2 |
x.hex() | 表示将浮点值 x 转化为以 16 进制表示的字符串。如2.4.hex() ,其返回值为'0x1.3333333333333p+1' (用 p 来表示幂,因为 e 是一个有效的 16 进制数) |
float.fromhex(x) | 表示将 16 进制的 x 转化为浮点型。如x = 2.4.hex() s = float.fromhex(x) ,其返回值为2.4 |
与整型转换类似,浮点型也可以进行数据类型转化( float()
),不提供参数情况下,返回默认值 0.0。
介于浮点型很多方法和整型类似,这里不作过多赘述。
结语
不同数据类型里,有着很多相关的函数、方法,初学 Python 的同学,其实并不需要每个都深究,只需要掌握几个常用的即可,当你遇到的时候,再去搜一些相关博客,或者上官网都可以。
当然最好的方法还是直接在 IDE 里面通过help
查询,help
就是程序员在设计 Python 时,为 Python 里面的每个函数写的注释。所以想要知道一个函数有什么作用,最好的方法就是直接查看他的注释,也就是使用help
查看。
help
函数可以说是整个 Python 里面最重要的函数都不为过!
推荐阅读
Python 中的八大关键要素
您的一次关注就足以让我感动!
更多推荐
Python 中的固定类型
发布评论