2024年【Python学习教程】Python变量类型和运算符_python 变量运算

f5 = 12e4
print("f5Value: ", f5)
print("f5Type: ", type(f5))
f6 = 12.3 * 0.1
print("f6Value: ", f6)
print("f6Type: ", type(f6))


运行结果:


f1Value: 12.5  
 f1Type: <class ‘float’>  
 f2Value: 0.34557808421257  
 f2Type: <class ‘float’>  
 f3Value: 8.47e-26  
 f3Type: <class ‘float’>  
 f4Value: 3.456797451324568e+26  
 f4Type: <class ‘float’>  
 f5Value: 120000.0  
 f5Type: <class ‘float’>  
 f6Value: 1.2300000000000002  
 f6Type: <class ‘float’>


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


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


让人奇怪的是 f6,`12.3*0.1`的计算结果很明显是 1.23,但是 print 的输出却不精确。这是因为小数在内存中是以二进制形式存储的,小数点后面的部分在转换成二进制时很有可能是一串无限循环的数字,无论如何都不能精确表示,所以小数的计算结果一般都是不精确的。有兴趣的读者请猛击下面的链接深入学习:


* [进制转换:二进制、八进制、十六进制、十进制之间的转换]( )
* [小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)]( )


## Python复数类型(complex)详解


复数(Complex)是 [Python]( ) 的内置类型,直接书写即可。换句话说,Python 语言本身就支持复数,而不依赖于标准库或者第三方库。


复数由实部(real)和虚部(imag)构成,在 Python 中,复数的虚部以`j`或者`J`作为后缀,具体格式为:


a + bj


a 表示实部,b 表示虚部。


【实例】Python 复数的使用:



c1 = 12 + 0.2j
print("c1Value: ", c1)
print(“c1Type”, type(c1))
c2 = 6 - 1.2j
print("c2Value: ", c2)
#对复数进行简单计算
print("c1+c2: ", c1+c2)
print("c1*c2: ", c1*c2)


运行结果:


c1Value: (12+0.2j)  
 c1Type <class ‘complex’>  
 c2Value: (6-1.2j)  
 c1+c2: (18-1j)  
 c1\*c2: (72.24-13.2j)


可以发现,复数在 Python 内部的类型是 complex,Python 默认支持对复数的简单计算。


## Python浮点数精度问题(包含解决方案)


前面章节提到,Python 中浮点类型之间的运算,其结果并不像我们想象的那样,例如:


>>> 0.1+0.2  
 0.30000000000000004  
 >>> 0.1+0.1-0.2  
 0.0  
 >>> 0.1+0.1+0.1-0.3  
 5.551115123125783e-17  
 >>> 0.1+0.1+0.1-0.2  
 0.10000000000000003


为什么在计算这么简单的问题上,计算机会出现这样的低级错误呢?真正的原因在于十进制和数和二进制数的转换。


我们知道,计算机其实是不认识十进制数,它只认识二进制数,也就是说,当我们以十进制数进行运算的时候,计算机需要将各个十进制数转换成二进制数,然后进行二进制间的计算。


以类似 0.1 这样的浮点数为例,如果手动将其转换成二进制,其结果为:


0.1(10)=0.00011001100110011…(2)


可以看到,结果是无限循环的,也就是说,0.1 转换成二进制数后,无法精确到等于十进制数的 0.1。同时,由于计算机存储的位数是有限制的,所以如果要存储的二进制位数超过了计算机存储位数的最大值,其后续位数会被舍弃(舍弃的原则是“0 舍 1 入”)。



> 
> 这种问题不仅在 Python 中存在,在所有支持浮点数运算的编程语言中都会遇到,它不光是 Python 的 Bug。
> 
> 
> 


明白了问题产生的原因之后,那么该如何解决呢?就 Python 的浮点数运算而言,大多数计算机每次计算误差不会超过 253,这对于大多数任务来说已经足够了。


如果需要非常精确的结果,可以使用 decimal 模块(其实就是别人开发好的程序,我们可以直接拿来用),它实现的十进制数运算适合会计方面的应用和有高精度要求的应用。例如:



#使用模块前,需要使用 import 引入
import decimal
a = decimal.Decimal(“10.0”)
b = decimal.Decimal(“3”)
print(10.0/3)
print(a/b)


运行结果为:


3.3333333333333335  
 3.333333333333333333333333333


可以看到,相比普通运算的结果,使用 decimal 模块得到的结果更精确。


如果 decimal 模块还是无法满足需求,还可以使用 fractions 模块,例如:



#引入 decimal 模块
from fractions import Fraction
print(10/3)
print(Fraction(10,3))


运行结果为:


3.3333333333333335  
 10/3


可以看到,通过 fractions 模块能很好地解决浮点类型数之间运算的问题。



> 
> 本节涉及到了有关模块的使用,读者不用研究细节,会用即可,后续章节会详细介绍模块。
> 
> 
> 


## Python字符串详解(包含长字符串和原始字符串)


若干个字符的集合就是一个字符串(String)。[Python]( ) 中的字符串必须由双引号`" "`或者单引号`' '`包围,具体格式为:


“字符串内容”  
 ‘字符串内容’


字符串的内容可以包含字母、标点、特殊符号、中文、日文等全世界的所有文字。


下面都是合法的字符串:


* “123789”
* “123abc”
* “http://c.biancheng.net/python/”
* “C语言中文网成立8年了”


Python 字符串中的双引号和单引号没有任何区别。而有些编程语言的双引号字符串可以解析变量,单引号字符串一律原样输出,例如 [PHP]( ) 和 [JavaScript]( )。


### 处理字符串中的引号的


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


‘I’m a great coder!’


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


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


##### 1) 对引号进行转义


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



str1 = ‘I’m a great coder!’
str2 = “引文双引号是”,中文双引号是“"
print(str1)
print(str2)


运行结果:


I’m a great coder!  
 引文双引号是",中文双引号是“


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


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



str1 = “I’m a great coder!” #使用双引号包围含有单引号的字符串
str2 = ‘引文双引号是",中文双引号是“’ #使用单引号包围含有双引号的字符串
print(str1)
print(str2)


运行结果和上面相同。


### 字符串的换行


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



s2 = ‘It took me six months to write this Python tutorial.
Please give me more support.
I will keep it updated.’


上面 s2 字符串的比较长,所以使用了转义字符`\`对字符串内容进行了换行,这样就可以把一个长字符串写成多行。


另外,Python 也支持表达式的换行,例如:



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


### Python长字符串


在《[Python注释]( )》一节中我们提到,使用三个单引号或者双引号可以对多行内容进行注释,这其实是 Python 长字符串的写法。所谓长字符串,就是可以直接换行(不用加反斜杠`\`)书写的字符串。


Python 长字符串由三个双引号`"""`或者三个单引号`'''`包围,语法格式如下:


“”“长字符串内容”""  
 ‘’‘长字符串内容’’’


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


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


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


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


【实例】将长字符串赋值给变量:



longstr = ‘’‘It took me 6 months to write this Python tutorial.
Please give me a to ‘thumb’ to keep it updated.
The Python tutorial is available at http://c.biancheng.net/python/.’‘’
print(longstr)


长字符串中的换行、空格、缩进等空白符都会原样输出,所以你不能写成下面的样子:



longstr = ‘’’
It took me 6 months to write this Python tutorial.
Please give me a to ‘thumb’ to keep it updated.
The Python tutorial is available at http://c.biancheng.net/python/.
‘’’
print(longstr)


虽然这样写格式优美,但是输出结果将变成:


It took me 6 months to write this Python tutorial.  
 Please give me a to ‘thumb’ to keep it updated.  
 The Python tutorial is available at http://c.biancheng.net/python/.


字符串内容前后多出了两个空行,并且每一行的前面会多出四个空格。


### Python原始字符串


Python 字符串中的反斜杠`\`有着特殊的作用,就是转义字符,例如上面提到的`\'`和`\"`,我们将在《[Python转义字符]( )》一节中详细讲解,这里大家先简单了解。


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


这种写法需要特别谨慎,稍有疏忽就会出错。为了解决转义字符的问题,Python 支持原始字符串。在原始字符串中,`\`不会被当作转义字符,所有的内容都保持“原汁原味”的样子。


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


str1 = r’原始字符串内容’  
 str2 = r""“原始字符串内容”""


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



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


##### 原始字符串中的引号


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


请看下面的代码:



str1 = r’I’m a great coder!’
print(str1)


输出结果:


I’m a great coder!


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


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


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



str1 = r’D:\Program Files\Python 3.8’ ‘\’
print(str1)


我们先写了一个原始字符串`r'D:\Program Files\Python 3.8'`,紧接着又使用`'\\'`写了一个包含转义字符的普通字符串,Python 会自动将这两个字符串拼接在一起,所以上面代码的输出结果是:


D:\Program Files\Python 3.8\


由于这种写法涉及到了字符串拼接的相关知识,这里读者只需要了解即可,后续会对字符串拼接做详细介绍。


## Python字符串使用哪种编码格式?


在实践中,很多初学者都遇到过“文件显示乱码”的情况,其多数都是由于在打开文件时,没有选对编码格式导致的。因此,学习 Python 中的字符或字符串,了解其底层的编码格式是非常有必要的。


鉴于有些读者并不了解什么是编码格式,本节先从编码开始讲起。


### 什么是编码?


虽然很多教程中有关于编码的定义,但对初学者来说并不容易理解,这里先举一个例子。古代打仗,击鼓为号、鸣金收兵,即把要传达给士兵的命令对应为公认的其他形式,这就和编码有相似之处。


以发布进攻命令为例,相比用嗓子喊,敲鼓发出的声音传播的更远,并且士兵听到后也不会引起歧义,因此长官下达进攻命令后,传令员就将此命令转化为对应的鼓声,这个转化的过程称为编码;由于士兵都接受过训练,听到鼓声后,他们可以将其转化为对应的进攻命令,这个转化的过程称为解码。



> 
> 需要说明的是,此例只是形象地描述了编码和解码的原理,真实的编码和解码过程比这要复杂的多。
> 
> 
> 


了解了编码的含义之后,接下来再介绍一下字符编码。


### 什么是字符编码?


我们知道,计算机是以二进制的形式来存储数据的,即它只认识 0 和 1 两个数字。 20 世纪 60 年代,是计算机发展的早期,这时美国是计算机领域的老大,它制定了一套编码标准,解决了 128 个英文字符与二进制之间的对应关系,被称为 ASCII 字符编码(简称 ASCII 码)。



> 
> ASCII 码,全称为美国信息交换标准代码,是基于拉丁字母的一套字符编码,主要用于显示现代英语,因为万维网的出现,使得 ASCII 码广为使用,其直到 2007 年 12 月才逐渐被 Unicode 取代。
> 
> 
> 


虽然英语用 128 个字符编码已经够用,但计算机不仅仅用于英语,如果想表示其他语言,128 个符号显然不够用,所以很多其他国家都在 ASCII 的基础上发明了很多别的编码,例如包含了汉语简体中文格式的 GB2312 编码格式(使用 2 个字节表示一个汉字)。


也正是由于出现了很多种编码格式,导致了“文件显示乱码”的情况。比如说,发送邮件时,如果发信人和收信人使用的编码格式不一样,则收信人很可能看到乱码的邮件。基于这个原因,Unicode 字符集应运而生。


Unicode 字符集又称万国码、国际码、统一码等。从名字就可以看出来,它是以统一符号为目标的字符集。Unicode 对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更简单的方式来呈现和处理文字。


注意,在实际使用时,人们常常混淆字符集和字符编码这两个概念,我认为它们是不同的:


* 字符集定义了字符和二进制的对应关系,为每个字符分配了唯一的编号。可以将字符集理解成一个很大的表格,它列出了所有字符和二进制的对应关系,计算机显示文字或者存储文字,就是一个查表的过程;
* 而字符编码规定了如何将字符的编号存储到计算机中,要知道,有些字符编码(如 GB2312 和 GBK)规定,不同字符在存储时所占用的字节数是不一样的,因此为了区分一个字符到底使用了几个字节,就不能将字符的编号直接存储到计算机中,字符编号在存储之前必须要经过转换,在读取时还要再逆向转换一次,这套转换方案就叫做字符编码。


Unicode 字符集可以使用的编码方案有三种,分别是:


1. UTF-8:一种变长的编码方案,使用 1~6 个字节来存储;
2. UTF-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
3. UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。


其中,UTF-8 是目前使用最广的一种 Unicode字符集的实现方式,可以说它几乎已经一统江湖了。


### Python使用哪种字符编码?


了解了什么是编码,以及什么是字符编码之后,最后解决“Python 使用哪种字符编码?”这个问题。


Python 3.x 中,字符串采用的是 Unicode 字符集,可以用如下代码来查看当前环境的编码格式:


>>> import sys  
 >>> sys.getdefaultencoding()  
 ‘utf-8’


同时,在 Python 3.x 中也可以用 ord() 和 chr() 函数实现字符和编码数字之间的转换,例如:


>>> ord(‘Q’)  
 81  
 >>> chr(81)  
 ‘Q’  
 >>> ord(“网”)  
 32593  
 >>> chr(32593)  
 ‘网’



> 
> Python 2.x 中无法使用 ord() 得到指定字符对应的编码数字。
> 
> 
> 


由此可以知道,在 Unicode 字符集中,字符‘Q’对应的编码数字为 81,而中文‘网’对应的编码数字为 32593。


值得一提的是,虽然 Python 默认采用 UTF-8 编码,但它也提供了 encode() 方法,可以轻松实现将 Unicode 编码格式的字符串转化为其它编码格式。有关 encode() 方法的用法,可阅读《[Python encode()和decode()方法]( )》 一节。


## Python bytes类型及用法


[Python]( ) bytes 类型用来表示一个字节串。“字节串“不是编程术语,是我自己“捏造”的一个词,用来和字符串相呼应。


bytes 是 Python 3.x 新增的类型,在 Python 2.x 中是不存在的。


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


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


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


说白了,bytes 只是简单地记录内存中的原始数据,至于如何使用这些数据,bytes 并不在意,你想怎么使用就怎么使用,bytes 并不约束你的行为。


bytes 类型的数据非常适合在互联网上传输,可以用于网络通信编程;bytes 也可以用来存储图片、音频、视频等二进制格式的文件。


字符串和 bytes 存在着千丝万缕的联系,我们可以通过字符串来创建 bytes 对象,或者说将字符串转换成 bytes 对象。有以下三种方法可以达到这个目的:


* 如果字符串的内容都是 ASCII 字符,那么直接在字符串前面添加`b`前缀就可以转换成 bytes。
* bytes 是一个类,调用它的构造方法,也就是 bytes(),可以将字符串按照指定的字符集转换成 bytes;如果不指定字符集,那么默认采用 UTF-8。
* 字符串本身有一个 encode() 方法,该方法专门用来将字符串按照指定的字符集转换成对应的字节串;如果不指定字符集,那么默认采用 UTF-8。


【实例】使用不同方式创建 bytes 对象:



#通过构造函数创建空 bytes
b1 = bytes()
#通过空字符串创建空 bytes
b2 = b’’
#通过b前缀将字符串转换成 bytes
b3 = b’http://c.biancheng.net/python/’
print("b3: ", b3)
print(b3[3])
print(b3[7:22])
#为 bytes() 方法指定字符集
b4 = bytes(‘C语言中文网8岁了’, encoding=‘UTF-8’)
print("b4: ", b4)
#通过 encode() 方法将字符串转换成 bytes
b5 = “C语言中文网8岁了”.encode(‘UTF-8’)
print("b5: ", b5)


运行结果:


b3: b’http://c.biancheng.net/python/’  
 112  
 b’c.biancheng.net’  
 b4: b’C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x918\xe5\xb2\x81\xe4\xba\x86’  
 b5: b’C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x918\xe5\xb2\x81\xe4\xba\x86’


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


如果你对进制不了解,请猛击:


* [进制详解:二进制、八进制和十六进制]( )
* [进制转换:二进制、八进制、十六进制、十进制之间的转换]( )


如果你对字符集(字符编码)不了解,请猛击:


* [ASCII编码,将英文存储到计算机]( )
* [GB2312编码和GBK编码,将中文存储到计算机]( )
* [Unicode字符集,将全世界的文字存储到计算机]( )


bytes 类也有一个 decode() 方法,通过该方法可以将 bytes 对象转换为字符串。紧接上面的程序,添加以下代码:



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


输出结果:


str1: C语言中文网8岁了


## Python bool布尔类型


[Python]( ) 提供了 bool 类型来表示真(对)或假(错),比如常见的`5 > 3`比较算式,这个是正确的,在程序世界里称之为真(对),Python 使用 True 来代表;再比如`4 > 20`比较算式,这个是错误的,在程序世界里称之为假(错),Python 使用 False 来代表。


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


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


>>> False+1  
 1  
 >>> True+1  
 2


注意,这里只是为了说明 True 和 Flase 对应的整型值,在实际应用中是不妥的,不要这么用。


总的来说,bool 类型就是用于代表某个事情的真(对)或假(错),如果这个事情是正确的,用 True(或 1)代表;如果这个事情是错误的,用 False(或 0)代表。


【例 1】


>>> 5>3  
 True  
 >>> 4>20  
 False


在 Python 中,所有的对象都可以进行真假值的测试,包括字符串、元组、列表、字典、对象等,由于目前尚未学习,因此这里不做过多讲述,后续遇到时会做详细的介绍。


## Python缓存重用机制


Python 缓冲机制是为提高程序执行的效率服务的,实际上就是在 Python 解释器启动时从内存空间中开辟出一小部分,用来存储高频使用的数据,这样可以大大减少高频使用的数据创建时申请内存和销毁时撤销内存的开销。


Python 在存储数据时,会根据数据的读取频繁程度以及内存占用情况来考虑,是否按照一定的规则将数据存储缓存中。那么问题来了,内存重用机制适用于哪些基本数据类型呢?


表 1 罗列了 Python 是否将指定数据存入缓存中的规则:




| 数据类型 | 是否可以重用 | 生效范围 |
| --- | --- | --- |
| 范围在 [-5, 256] 之间的小整数 | 如果之前在程序中创建过,就直接存入缓存,后续不再创建。 | 全局 |
| bool 类型 |  |  |
| 字符串类型数据 |  |  |
| 大于 256 的整数 | 只要在本代码块内创建过,就直接缓存,后续不再创建。 | 本代码块 |
| 大于 0 的浮点型小数 |  |  |
| 小于 0 的浮点型小数 | 不进行缓存,每次都需要额外创建。 |  |
| 小于 -5 的整数 |  |  |


下面直接通过一段程序来演示 Python 缓存机制的规则。



#范围在 [-5, 256] 之间的小整数
int1 = -5
int2 = -5
print(“[-5, 256] 情况下的两个变量:”, id(int1), id(int2))
#bool类型
bool1 = True
bool2 = True
print(“bool类型情况下的两个变量:”,id(bool1),id(bool2))
#对于字符串
s1 = “3344”
s2 = “3344”
print(“字符串情况下的两个交量”, id(s1), id(s2))
#大于 256 的整数
int3 = 257
int4 = 257
print(“大于 256 的整数情况下的两个变量”, id(int3), id(int4))
#大于 0 的浮点数
f1 = 256.4
f2 = 256.4
print(“大于 0 的浮点数情况下的两个变量”, id(f1), id(f2))
#小于 0 的浮点数
f3 = -2.45
f4 = -2.45
print(“小于 0 的浮点数情况下的两个变量”, id(f3), id(f4))
#小于 -5 的整数
n1 = -6
n2 = -6
print(“小于 -5 的整数情况下的两个变量”, id(n1), id(n2))


注意,此程序中,大量使用 id() 内置函数,该函数的功能是获取变量(对象)所在的内存地址。运行该程序,其输出结果为:


[-5, 256] 情况下的两个变量: 1792722416 1792722416  
 bool类型情况下的两个变量: 1792241888 1792241888  
 字符串情况下的两个交量 2912801330712 2912801330712  
 大于 256 的整数情况下的两个变量 2912801267920 2912801267920  
 大于 0 的浮点数情况下的两个变量 2912762210728 2912762210728  
 小于 0 的浮点数情况下的两个变量 2912762211016 2912762211040  
 小于 -5 的整数情况下的两个变量 2912801267952 2912801267984


以上输出结果中,每行都输出了 2 个相对应的变量所在的内存地址,如果相等,则表明 Python 内部对其使用了缓存机制,反之则没有。读者可对照以上输出结果来理解表 1 中有关变量缓存机制的规则。


另外,对于表 1 中所提到的代码块,Python 中的函数和类都被认为是在程序中开辟了一块新的代码块。以函数为例,函数内部的代码分属一个代码块,函数外部的代码属于另一个代码块。



> 
> 有关函数的具有用法,后续章节会详细介绍,这里读者只需要知道函数中包含的代码,属于一个新的代码块即可。
> 
> 
> 


由表 1 可以看到,Python 缓存机制在不同的代码块中也会有不同的表现。举一个例子,在上面例子代码的基础上,继续编写如下程序:



def fun():
#[-5,256]
int1 = -5
print(“fun中 -5 的存储状态”,id(int1), id(int2))

#bool类型
bool3 = True
print("fun中 bool 类型的存储状态",id(bool3),id(bool2))

#字符串类型
s1 = "3344"
print("fun 中 3344 字符串的存储状态", id(s1), id(s2))
#大于 256
int3 = 257
print("fun中 257 的存储状态", id(int3), id(int4))
#浮点类型
f1 = 256.4
print("fun 中 256.4 的存储状态",id(f1), id(f2))
#小于 -5
n1 = -6
print("fun 中 -6 的存储状态", id(n1), id(n2))

fun()


输出结果为:


fun中 -5 的存储状态 1792722416 1792722416  
 fun中 bool 类型的存储状态 1792241888 1792241888  
 fun 中 3344 字符串的存储状态 1976405206496 1976405206496  
 fun中 257 的存储状态 1976405225648 1976405225680  
 fun 中 256.4 的存储状态 1976394459752 1976394459872  
 fun 中 -6 的存储状态 1976404744880 1976405225744


根据输出结果可以分析出:


1. 从 -5 、bool 类型以及字符串 “3344” 的输出结果可以得知,无论是在同一代码块,还是不同的代码块,它们都使用相同的缓存内容;
2. 从 257 和 256.4 的输出结果可以得知,如果位于同一代码块,则使用相同的缓存内容;反之,则不使用;
3. 从 -6 的输出结果得知,Python 没有对其缓存进行操作。


## Python input()函数:获取用户输入的字符串


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


input() 函数的用法为:


str = input(tipmsg)


说明:


* str 表示一个字符串类型的变量,input 会将读取到的字符串放入 str 中。
* tipmsg 表示提示信息,它会显示在控制台上,告诉用户应该输入什么样的内容;如果不写 tipmsg,就不会有任何提示信息。


【实例】input() 函数的简单使用:



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))


运行结果示例:


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 类型。


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



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))


运行结果:


Enter a number: 12.5↙  
 Enter another number: 64↙  
 aType: <class ‘float’>  
 bType: <class ‘int’>  
 resultValue: 76.5  
 resultType: <class ‘float’>


### 关于 Python 2.x


上面讲解的是 Python 3.x 中 input() 的用法,但是在较老的 Python 2.x 中情况就不一样了。Python 2.x 共提供了两个输入函数,分别是 input() 和 raw\_input():


* Python 2.x raw\_input() 和 Python 3.x input() 效果是一样的,都只能以字符串的形式读取用户输入的内容。
* Python 2.x input() 看起来有点奇怪,它要求用户输入的内容必须符合 Python 的语法,稍有疏忽就会出错,通常来说只能是整数、小数、复数、字符串等。


比较强迫的是,Python 2.x input() 要求用户在输入字符串时必须使用引号包围,这有违 Python 简单易用的原则,所以 Python 3.x 取消了这种输入方式。


修改本节第一段代码,去掉 print 后面的括号:



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)


在 Python 2.x 下运行该代码:


Enter a number: 45↙  
 Enter another number: 100↙  
 aType: <type ‘int’>  
 bType: <type ‘int’>  
 resultValue: 145  
 resultType: <type ‘int’>


## Python print()函数高级用法


前面使用 print() 函数时,都只输出了一个变量,但实际上 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=”")


上面三条 print() 语句会执行三次输出,但由于它们都指定了 end="",因此每条 print() 语句的输出都不会换行,依然位于同一行。运行上面代码,可以看到如下输出结果:


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格式化字符串(格式化输出)


我们在《[第一个Python程序——在屏幕上输出文本]( )》中讲到过 print() 函数的用法,这只是最简单最初级的形式,print() 还有很多高级的玩法,比如格式化输出,这就是本节要讲解的内容。


熟悉C语言 printf() 函数的读者能够轻而易举学会 [Python]( ) print() 函数,它们是非常类似的。


print() 函数使用以`%`开头的转换说明符对各种类型的数据进行格式化输出,具体请看下表。




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


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


【实例】输出一个整数:



age = 8
print(“C语言中文网已经%d岁了!” % age)


运行结果:  
 C语言中文网已经8岁了!


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


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


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



name = “C语言中文网”
age = 8
url = “http://c.biancheng.net/”
print(“%s已经%d岁了,它的网址是%s。” % (name, age, url))


运行结果:


C语言中文网已经8岁了,它的网址是http://c.biancheng.net/。


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


### 指定最小输出宽度


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


* %10d 表示输出的整数宽度至少为 10;
* %20s 表示输出的字符串宽度至少为 20。


请看下面的演示:



n = 1234567
print(“n(10):%10d.” % n)
print(“n(5):%5d.” % n)
url = “http://c.biancheng.net/python/”
print(“url(35):%35s.” % url)
print(“url(20):%20s.” % url)


运行结果:



n(10): 1234567.
n(5):1234567.
url(35): http://c.biancheng.net/python/.
url(20):http://c.biancheng.net/python/.


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


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


### 指定对齐方式


默认情况下,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)


运行结果:



n(09):000123456
n(+9): +123456
f(-+0):+140.500000
s(-10):Hello .


### 指定小数精度


对于小数(浮点数),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)


运行结果:



3.142
0003.142
+003.142


## Python转义字符及用法


在《[Python字符串]( )》一节中我们曾提到过转义字符,就是那些以反斜杠`\`开头的字符。


ASCII 编码为每个字符都分配了唯一的编号,称为编码值。在 [Python]( ) 中,一个 ASCII 字符除了可以用它的实体(也就是真正的字符)表示,还可以用它的编码值表示。这种使用编码值来间接地表示字符的方式称为转义字符(Escape Character)。


如果你对 ASCII 编码不了解,请猛击:


* [ASCII 编码,将英文存储到计算机]( )
* [ASCII 码一览表,ASCII 码对照表(完整版)]( )


转义字符以`\0`或者`\x`开头,以`\0`开头表示后跟八进制形式的编码值,以`\x`开头表示后跟十六进制形式的编码值,Python 中的转义字符只能使用八进制或者十六进制。具体格式如下:


\0dd  
 \xhh


dd 表示八进制数字,hh 表示十六进制数字。


ASCII 编码共收录了 128 个字符,`\0`和`\x`后面最多只能跟两位数字,所以八进制形式`\0`并不能表示所有的 ASCII 字符,只有十六进制形式`\x`才能表示所有 ASCII 字符。


我们一直在说 ASCII 编码,没有提及 Unicode、GBK、Big5 等其它编码(字符集),是因为 Python 转义字符只对 ASCII 编码(128 个字符)有效,超出范围的行为是不确定的。


字符 1、2、3、x、y、z 对应的 ASCII 码的八进制形式分别是 61、62、63、170、171、172,十六进制形式分别是 31、32、33、78、79、7A。下面的例子演示了转义字符的用法:



str1 = “Oct: \061\062\063”
str2 = “Hex: \x31\x32\x33\x78\x79\x7A”
print(str1)
print(str2)


运行结果:


Oct: 123  
 Hex: 123xyz


注意,使用八进制形式的转义字符没法表示 xyz,因为它们的编码值转换成八进制以后有三位。


对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以,针对常用的控制字符,C语言又定义了简写方式,完整的列表如下。




| 转义字符 | 说明 |
| --- | --- |
| \n | 换行符,将光标位置移到下一行开头。 |
| \r | 回车符,将光标位置移到本行开头。 |
| \t | 水平制表符,也即 Tab 键,一般相当于四个空格。 |
| \a | 蜂鸣器响铃。注意不是喇叭发声,现在的计算机很多都不带蜂鸣器了,所以响铃不一定有效。 |
| \b | 退格(Backspace),将光标位置移到前一列。 |
| \ | 反斜线 |
| ’ | 单引号 |
| " | 双引号 |
| \ | 在字符串行尾的续行符,即一行未完,转到下一行继续写。 |


转义字符在书写形式上由多个字符组成,但 Python 将它们看作是一个整体,表示一个字符。


Python 转义字符综合示例:



#使用\t排版
str1 = ‘网站\t\t域名\t\t\t年龄\t\t价值’
str2 = ‘C语言中文网\tc.biancheng.net\t\t8\t\t500W’
str3 = ‘百度\t\twww.baidu.com\t\t20\t\t500000W’
print(str1)
print(str2)
print(str3)
print(“--------------------”)

\n在输出时换行,\在书写字符串时换行

info = “Python教程:http://c.biancheng.net/python/\n
C++教程:http://c.biancheng.net/cplus/\n
Linux教程:http://c.biancheng.net/linux_tutorial/”
print(info)


运行结果:



网站 域名 年龄 价值
C语言中文网 c.biancheng.net 8 500W
百度 www.baidu.com 20 500000W

Python教程:http://c.biancheng.net/python/
C++教程:http://c.biancheng.net/cplus/
Linux教程:http://c.biancheng.net/linux_tutorial/


## Python类型转换,Python数据类型转换函数大全


虽然 [Python]( ) 是弱类型编程语言,不需要像 [Java]( ) 或 C 语言那样还要在使用变量前声明变量的类型,但在一些特定场景中,仍然需要用到类型转换。


比如说,我们想通过使用 print() 函数输出信息“您的身高:”以及浮点类型 height 的值,如果在交互式解释器中执行如下代码:


>>> height = 70.0  
 >>> print(“您的身高”+height)  
 Traceback (most recent call last):  
 File “<pyshell#1>”, line 1, in   
 print(“您的身高”+height)  
 TypeError: must be str, not float


你会发现这是错误的,解释器提示我们字符串和浮点类型变量不能直接相连,需要提前将浮点类型变量 height 转换为字符串才可以。


庆幸的是,Python 已经为我们提供了多种可实现数据类型转换的函数,如表 1 所示。




| 函 数 | 作 用 |
| --- | --- |
| 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 转换为一个八进制的字符串 |


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


>>> int(“123”) #转换成功  
 123  
 >>> int(“123个”) #转换失败  
 Traceback (most recent call last):  
 File “<pyshell#3>”, line 1, in   
 int(“123个”)  
 ValueError: invalid literal for int() with base 10: ‘123个’  
 >>>


## Python算术运算符及用法详解


算术运算符也即数学运算符,用来对数字进行数学运算,比如加减乘除。下表列出了 [Python]( ) 支持所有基本算术运算符。




| 运算符 | 说明 | 实例 | 结果 |
| --- | --- | --- | --- |
| + | 加 | 12.45 + 15 | 27.45 |
| - | 减 | 4.56 - 0.26 | 4.3 |
| \* | 乘 | 5 \* 3.6 | 18.0 |
| / | 除法(和数学中的规则一样) | 7 / 2 | 3.5 |
| // | 整除(只保留商的整数部分) | 7 // 2 | 3 |
| % | 取余,即返回除法的余数 | 7 % 2 | 1 |
| \*\* | 幂运算/次方运算,即返回 x 的 y 次方 | 2 \*\* 4 | 16,即 24 |


接下来将对表 1 中各个算术运算符的用法逐一讲解。


### + 加法运算符


加法运算符很简单,和数学中的规则一样,请看下面的代码:



m = 10
n = 97
sum1 = m + n
x = 7.2
y = 15.3
sum2 = x + y
print(“sum1=%d, sum2=%.2f” % (sum1, sum2) )


运行结果:  
 sum1=107, sum2=22.50


##### 拼接字符串


当`+`用于数字时表示加法,但是当`+`用于字符串时,它还有拼接字符串(将两个字符串连接为一个)的作用,请看代码:



name = “C语言中文网”
url = “http://c.biancheng.net/”
age = 8
info = name + “的网址是” + url + “,它已经” + str(age) + “岁了。”
print(info)


运行结果:


C语言中文网的网址是http://c.biancheng.net/,它已经8岁了。


str() 函数用来将整数类型的 age 转换成字符串。


### - 减法运算符


减法运算也和数学中的规则相同,请看代码:



n = 45
m = -n
x = -83.5
y = -x
print(m, “,”, y)


运行结果:  
 -45 , 83.5


##### 求负


`-`除了可以用作减法运算之外,还可以用作求负运算(正数变负数,负数变正数),请看下面的代码:



n = 45
n_neg = -n
f = -83.5
f_neg = -f
print(n_neg, “,”, f_neg)


运行结果:  
 -45 , 83.5


注意,单独使用`+`是无效的,不会改变数字的值,例如:



n = 45
m = +n
x = -83.5
y = +x
print(m, “,”, y)


运行结果:  
 45 , -83.5


### *乘法运算符


乘法运算也和数学中的规则相同,请看代码:



n = 4 * 25
f = 34.5 * 2
print(n, “,”, f)


运行结果:  
 100 , 69.0


##### 重复字符串


`*`除了可以用作乘法运算,还可以用来重复字符串,也即将 n 个同样的字符串连接起来,请看代码:



str1 = "hello "
print(str1 * 4)


运行结果:  
 hello hello hello hello


### / 和 // 除法运算符


Python 支持`/`和`//`两个除法运算符,但它们之间是有区别的:


* `/`表示普通除法,使用它计算出来的结果和数学中的计算结果相同。
* `//`表示整除,只保留结果的整数部分,舍弃小数部分;注意是直接丢掉小数部分,而不是四舍五入。


请看下面的例子:



#整数不能除尽
print(“23/5 =”, 23/5)
print(“23//5 =”, 23//5)
print(“23.0//5 =”, 23.0//5)
print(“-------------------”)
#整数能除尽
print(“25/5 =”, 25/5)
print(“25//5 =”, 25//5)
print(“25.0//5 =”, 25.0//5)
print(“-------------------”)
#小数除法
print(“12.4/3.5 =”, 12.4/3.5)
print(“12.4//3.5 =”, 12.4//3.5)


运行结果:


23/5 = 4.6  
 23//5 = 4  
 23.0//5 = 4.0  
 -------------------  
 25/5 = 5.0  
 25//5 = 5  
 25.0//5 = 5.0  
 -------------------  
 12.4/3.5 = 3.542857142857143  
 12.4//3.5 = 3.0


从运行结果可以发现:


* `/`的计算结果总是小数,不管是否能除尽,也不管参与运算的是整数还是小数。
* 当有小数参与运算时,`//`结果才是小数,否则就是整数。


需要注意的是,除数始终不能为 0,除以 0 是没有意义的,这将导致 ZeroDivisionError 错误。在某些编程语言中,除以 0 的结果是无穷大(包括正无穷大和负无穷大)。


##### Python 2.x 中的除法


Python 2.x 只提供了一种除法运算,就是`/`,它的行为和大部分编程语言中`/`的行为是一样的:


* 当`/`两边都是整数时,结果始终是整数;如果不能除尽,就直接舍弃小数部分。
* 当`/`两边有一个是小数时,结果始终是小数;如果恰好除尽,小数部分就是 0。


请看下面的代码:



#整数除法
print “18/6 =”, 18/6
print “47/7 =”, 47/7
print “----------------”
#小数除法
print “18.0/6 =”, 18.0/6
print “47.0/7 =”, 47.0/7
print “29.5/4.2 =”, 29.5/4.2


运行结果:


18/6 = 3  
 47/7 = 6  
 ----------------  
 18.0/6 = 3.0  
 47.0/7 = 6.71428571429  
 29.5/4.2 = 7.02380952381


你可以将 Python 2.x 中的`/`看作 Python 3.x 中`/`和`//`的结合体,因为 Python 2.x 中`/`的行为有点奇怪,所以 Python 3.x 增加了`//`运算符,用以规范除法运算的行为。


### % 求余运算符


Python % 运算符用来求得两个数相除的余数,包括整数和小数。Python 使用第一个数字除以第二个数字,得到一个整数的商,剩下的值就是余数。对于小数,求余的结果一般也是小数。


注意,求余运算的本质是除法运算,所以第二个数字也不能是 0,否则会导致 ZeroDivisionError 错误。


Python % 使用示例:



print(“-----整数求余-----”)
print(“15%6 =”, 15%6)
print(“-15%6 =”, -15%6)
print(“15%-6 =”, 15%-6)
print(“-15%-6 =”, -15%-6)
print(“-----小数求余-----”)
print(“7.7%2.2 =”, 7.7%2.2)
print(“-7.7%2.2 =”, -7.7%2.2)
print(“7.7%-2.2 =”, 7.7%-2.2)
print(“-7.7%-2.2 =”, -7.7%-2.2)
print(“—整数和小数运算—”)
print(“23.5%6 =”, 23.5%6)
print(“23%6.5 =”, 23%6.5)
print(“23.5%-6 =”, 23.5%-6)
print(“-23%6.5 =”, -23%6.5)
print(“-23%-6.5 =”, -23%-6.5)


运行结果:


-----整数求余-----  
 15%6 = 3  
 -15%6 = 3  
 15%-6 = -3  
 -15%-6 = -3  
 -----小数求余-----  
 7.7%2.2 = 1.0999999999999996  
 -7.7%2.2 = 1.1000000000000005  
 7.7%-2.2 = -1.1000000000000005  
 -7.7%-2.2 = -1.0999999999999996  
 —整数和小数运算—  
 23.5%6 = 5.5  
 23%6.5 = 3.5  
 23.5%-6 = -0.5  
 -23%6.5 = 3.0  
 -23%-6.5 = -3.5


从运行结果可以发现两点:


* 只有当第二个数字是负数时,求余的结果才是负数。换句话说,求余结果的正负和第一个数字没有关系,只由第二个数字决定。
* `%`两边的数字都是整数时,求余的结果也是整数;但是只要有一个数字是小数,求余的结果就是小数。


本例中小数求余的四个结果都不精确,而是近似值,这和小数在底层的存储有关系,有兴趣的读者请猛击《[小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)]( )》了解更多。


### \*\* 次方(乘方)运算符


Python \*\* 运算符用来求一个 x 的 y 次方,也即次方(乘方)运算符。


由于开方是次方的逆运算,所以也可以使用 \*\* 运算符间接地实现开方运算。


Python \*\* 运算符示例:



print(‘----次方运算----’)
print(‘3**4 =’, 3**4)
print(‘2**5 =’, 2**5)
print(‘----开方运算----’)
print(‘81**(1/4) =’, 81**(1/4))
print(‘32**(1/5) =’, 32**(1/5))


运行结果:


----次方运算----  
 3**4 = 81  
 2**5 = 32  
 ----开方运算----  
 81\*\*(1/4) = 3.0  
 32\*\*(1/5) = 2.0


## Python赋值运算符(入门必读)


赋值运算符用来把右侧的值传递给左侧的变量(或者常量);可以直接将右侧的值交给左侧的变量,也可以进行某些运算后再交给左侧的变量,比如加减乘除、函数调用、逻辑运算等。


[Python]( ) 中最基本的赋值运算符是等号`=`;结合其它运算符,`=`还能扩展出更强大的赋值运算符。


### 基本赋值运算符


`=`是 Python 中最常见、最基本的赋值运算符,用来将一个表达式的值赋给另一个变量,请看下面的例子:



#将字面量(直接量)赋值给变量
n1 = 100
f1 = 47.5
s1 = “http://c.biancheng.net/python/”
#将一个变量的值赋给另一个变量
n2 = n1
f2 = f1
#将某些运算的值赋给变量
sum1 = 25 + 46
sum2 = n1 % 6
s2 = str(1234) #将数字转换成字符串
s3 = str(100) + “abc”


##### 连续赋值


Python 中的赋值表达式也是有值的,它的值就是被赋的那个值,或者说是左侧变量的值;如果将赋值表达式的值再赋值给另外一个变量,这就构成了连续赋值。请看下面的例子:


a = b = c = 100


`=`具有右结合性,我们从右到左分析这个表达式:


* c = 100 表示将 100 赋值给 c,所以 c 的值是 100;同时,c = 100 这个子表达式的值也是 100。
* b = c = 100 表示将 c = 100 的值赋给 b,因此 b 的值也是 100。
* 以此类推,a 的值也是 100。


最终结果就是,a、b、c 三个变量的值都是 100。


##### = 和 ==


= 和 == 是两个不同的运算符,= 用来赋值,而 == 用来判断两边的值是否相等,千万不要混淆。


### 扩展后的赋值运算符


`=`还可与其他运算符(包括算术运算符、位运算符和逻辑运算符)相结合,扩展成为功能更加强大的赋值运算符,如表 1 所示。扩展后的赋值运算符将使得赋值表达式的书写更加优雅和方便。




| 运算符 | 说 明 | 用法举例 | 等价形式 |
| --- | --- | --- | --- |
| = | 最基本的赋值运算 | 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 |
| <<= | 左移赋值 | x <<= y | x = x << y,这里的 y 指的是左移的位数 |
| >>= | 右移赋值 | x >>= y | x = x >> y,这里的 y 指的是右移的位数 |


这里举个简单的例子:



n1 = 100
f1 = 25.5
n1 -= 80 #等价于 n1=n1-80
f1 = n1 - 10 #等价于 f1=f1( n1 - 10 )
print(“n1=%d” % n1)
print(“f1=%.2f” % f1)


运行结果为:  
 n1=20  
 f1=255.00


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


但是请注意,这种赋值运算符只能针对已经存在的变量赋值,因为赋值过程中需要变量本身参与运算,如果变量没有提前定义,它的值就是未知的,无法参与运算。例如,下面的写法就是错误的:


n += 10


该表达式等价于 n = n + 10,n 没有提前定义,所以它不能参与加法运算。


## Python位运算符详解


[Python]( ) 位运算按照数据在内存中的二进制位(Bit)进行操作,它一般用于底层开发(算法设计、驱动、图像处理、单片机等),在应用层开发(Web 开发、Linux 运维等)中并不常见。想加快学习进度,或者不关注底层开发的读者可以先跳过本节,以后需要的话再来学习。


Python 位运算符只能用来操作整数类型,它按照整数在内存中的二进制形式进行计算。Python 支持的位运算符如表 1 所示。




| 位运算符 | 说明 | 使用形式 | 举 例 |
| --- | --- | --- | --- |
| & | 按位与 | a & b | 4 & 5 |
| | | 按位或 | a | b | 4 | 5 |
| ^ | 按位异或 | a ^ b | 4 ^ 5 |
| ~ | 按位取反 | ~a | ~4 |
| << | 按位左移 | a << b | 4 << 2,表示整数 4 按位左移 2 位 |
| >> | 按位右移 | a >> b | 4 >> 2,表示整数 4 按位右移 2 位 |


### & 按位与运算符


按位与运算符`&`的运算规则是:只有参与`&`运算的两个位都为 1 时,结果才为 1,否则为 0。例如`1&1`为 1,`0&0`为 0,`1&0`也为 0,这和逻辑运算符`&&`非常类似。




| 第一个Bit位 | 第二个Bit位 | 结果 |
| --- | --- | --- |


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210511152217670.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaWd1aWd1,size_16,color_FFFFFF,t_70)

**感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:**



① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里无偿获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值