语言元素
指令和程序
计算机硬件系统通常由运算器、控制器、存储器、输入设备和输出设备五个部件组成。其中,运算器和控制器是我们通常所说的中央处理器,它的功能是执行各种操作和控制指令,并处理计算机软件中的数据。我们通常所说的程序实际上是指令的集合。我们的程序是以某种方式组织一系列指令,然后通过这些指令控制计算机做我们想做的事情。我们今天大部分时间使用的计算机,虽然它们的部件越来越精确,处理能力越来越强,但本质上仍然属于冯·诺依曼结构的计算机。“冯·诺依曼结构有两个关键点,一个是将存储设备与中央处理器分开,另一个是通过二进制编码数据。二进制是一种逢二进一的计数方法,与我们人类使用的逢十进一的计数方法没有实质性的区别。人类使用十进制是因为他们有十根手指(因为他们只能在数数时用完十根手指后进入位置)。当然,凡事都有例外。玛雅人可能会因为多年赤脚而计算脚趾,所以他们使用二十进制的计数方法,在这种计数法的指导下,玛雅人的历法不同于我们通常使用的历法。根据玛雅人的历法,2012年是所谓太阳纪的最后一年,2013年是新太阳纪的开始。后来,这件事被误传为2012年是玛雅人预言的世界末日。今天我们可以大胆猜测,据估计,玛雅文明发展缓慢也与使用二十进制有关)。对于计算机来说,二进制是物理器件上最容易实现的(高压表示1,低压表示0),所以在冯·诺依曼结构计算机均采用二进制。对于计算机来说,二进制是物理器件上最容易实现的(高压表示1,低压表示0),所以在冯·诺依曼结构的计算机采用二进制。虽然我们不需要每个程序员都能用二进制的思维方式工作,但有必要了解二进制及其与我们生活中十进制的转换关系,以及二进制与八进制与十六进制的转换关系。如果你不熟悉这一点,你可以自己使用维基百科全书或百度百科全书。
:近期关于这项研究已经被推到了风口浪尖,量子计算机基于量子力学运算,使用量子瞬移传递信息。2018年6月,Intel在接近绝对零度的环境下,宣布开发新量子芯片并通过测试;2019年,IBM和Google都推出了自己的量子计算机。
变量和类型
变量是程序设计中存储数据的载体。计算机中的变量是存储数据的实际数据或存储数据的内存空间,可以读取和修改变量值,这是所有计算和控制的基础。计算机可以处理的数据有很多种,除了文本、图形、音频、视频等数据,所以不同的数据需要定义不同的存储类型。Python有许多类型的数据,也允许我们定制新的数据类型(这将在后面提到),我们首先介绍几种常见的数据类型。
- 整型:Python可以处理任何大小的整数(Python 2.x中有
int
和long
两种类型的整数,但这种区别是正确的Python意义不大,所以在Python 3.x中整数只有int这个),支持二进制(如0b100
,转换成十进制是4),八进制(如0o100
,十进制是64,十进制是64(100
)和十六进制(0x100
,转换成十进制是256)。 - 浮点类型:浮点数,即小数,被称为浮点数,因为根据科学记数法,浮点数的小数点位置是可变的,(如
123.456
)还支持科学计数法(如1.23456e2
)。 - 字符串类型:字符串是由单引号或双引号包含的任何文本,如
'hello'
和"hello"
,字符串还有原始字符串的表达方式,字节字符串的表达方式,Unicode字符串表示法,可以写成多行形式(从三个单引号或三个双引号开始,三个单引号或三个双引号结束)。 - 布尔型:只有布尔值
True
、False
两个值,要么是True
,要么是False
,在Python可直接使用True
、False
也可以通过布尔计算表示布尔值(请注意大小写)(例如3 < 5
会产生布尔值True
,而2 == 1
会产生布尔值False
)。 - 复数型:形如
3 5j
,和数学复数一样,唯一不同的是虚部i
换成了j
。其实这种类型并不常用,大家可以了解一下。
变量命名
我们需要给每个变量起一个名字,就像我们每个人都有自己响亮的名字一样。Python变量命名应遵循以下非硬性规则,必须遵守硬性规则和强烈建议。
- 硬性规则:
- 变量名由字母(广义上Unicode不包括特殊字符)、数字和下划线,数字不能开始。
- 大写敏感(大写
a
和小写的A
是两个不同的变量)。 - 不要与系统保留字(如函数、模块等)冲突(具有特殊含义的单词,以后会提到)。
- PEP 8要求:
- 用小写字母拼写,用下划线连接多个单词。
- 受保护的实例属性从单个下划线开始(后面会提到)。
- 私有实例属性从两条下划线开始(后面会提到)。
当然,作为一名专业程序员,在命名变量(实际上应该是所有的标识符)时,也非常重要。
变量的使用
以下是变量类型和变量使用的几个例子。
""" 使用变量保存数据,加减乘除 Version: 0.1 """ a = 321 b = 12 print(a b) # 333 print(a - b) # 309 print(a * b) # 3852 print(a / b) # 26.75
在Python中可以使用type
函数检查变量的类型。程序设计中函数的概念与数学中函数的概念一致。我相信你对数学函数并不陌生。它包括函数名、自变量和因变量。如果我们暂时不理解这个概念也没关系。我们将在后续章节中解释函数的定义和使用。
""" 使用type()检查变量的类型 Version: 0.1 """ a = 100 b = 12.345 c = 1 5j d = 'hello, world' e = True print(type(a)) # <class 'int'> print(type(b)) # <class 'float'> print(type(c)) # <class 'complex'> print(type(d)) # <class 'str'> print(type(e)) # <class 'bool'>
可以使用Python中内置函数转换变量类型。
int()
:将数值或字符串转换为整数,可指定进制。float()
:将字符串转换为浮点数。str()
:将指定对象转换为字符串形式,可指定编码。chr()
:将整数转换为编码对应的字符串(一个字符)。ord()
:将字符串(一个字符)转换为相应的编码(整数)。
""" 使用input()函数获取键盘输入(字符串) 使用int()函数将输入的字符串转换成整数 使用print()函数输出带占位符的字符串 Version: 0.1 """ a = int(input('a = ')) b = int(input('b = ')) print('%d %d = %d' % (a, b, a b)) print('%d - %d = %d' % (a, b, a - b)) print('%d * %d = %d' % (a, b, a * b)) print('%d / %d = %f' % (a, b, a / b)) print('%d // %d = %d' % (a, b, a // b)) print('%d %% %d = %d' % (a, b, a % b)) print('%d ** %d = %d' % (a, b, a ** b))
:上面的print占位符语法用于函数中输出的字符串
%d
是整数占位符,%f
是小数的占位符,%%
表示百分号(因为百分号代表占位符,带占位符的字符串必须写成%%
),字符串之后%
后面跟的变值会替换掉占位符然后输出到终端中,运行上面的程序,看看程序执行结果就明白啦。
运算符
Python支持多种运算符,下表大致按照优先级从高到低的顺序列出了所有的运算符,运算符的优先级指的是多个运算符同时出现时,先做什么运算然后再做什么运算。除了我们之前已经用过的赋值运算符和算术运算符,我们稍后会陆续讲到其他运算符的使用。
运算符 | 描述 |
---|---|
[] [:] |
下标,切片 |
** |
指数 |
~ + - |
按位取反, 正负号 |
* / % // |
乘,除,模,整除 |
+ - |
加,减 |
>> << |
右移,左移 |
& |
按位与 |
^ | |
按位异或,按位或 |
<= < > >= |
小于等于,小于,大于,大于等于 |
== != |
等于,不等于 |
is is not |
身份运算符 |
in not in |
成员运算符 |
not or and |
逻辑运算符 |
= += -= *= /= %= //= **= &= ` |
= ^=` `>>=` `<<=` |
在实际开发中,如果搞不清楚运算符的优先级,可以使用括号来确保运算的执行顺序。
赋值运算符
赋值运算符应该是最为常见的运算符,它的作用是将右边的值赋给左边的变量。下面的例子演示了赋值运算符和复合赋值运算符的使用。
"""
赋值运算符和复合赋值运算符
Version: 0.1
"""
a = 10
b = 3
a += b # 相当于:a = a + b
a *= a + 2 # 相当于:a = a * (a + 2)
print(a) # 算一下这里会输出什么
比较运算符和逻辑运算符
比较运算符有的地方也称为关系运算符,包括==
、!=
、<
、>
、<=
、>=
,我相信没有什么好解释的,大家一看就能懂,唯一需要提醒的是比较相等用的是==
,请注意这个地方是两个等号,因为=
是赋值运算符,我们在上面刚刚讲到过,==
才是比较相等的比较运算符。比较运算符会产生布尔值,要么是True
要么是False
。
逻辑运算符有三个,分别是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
。
"""
比较运算符和逻辑运算符的使用
Version: 0.1
"""
flag0 = 1 == 1
flag1 = 3 > 2
flag2 = 2 < 1
flag3 = flag1 and flag2
flag4 = flag1 or flag2
flag5 = not (1 != 2)
print('flag0 =', flag0) # flag0 = True
print('flag1 =', flag1) # flag1 = True
print('flag2 =', flag2) # flag2 = False
print('flag3 =', flag3) # flag3 = False
print('flag4 =', flag4) # flag4 = True
print('flag5 =', flag5) # flag5 = False
:比较运算符的优先级高于赋值运算符,所以
flag0 = 1 == 1
先做1 == 1
产生布尔值True
,再将这个值赋值给变量flag0
。,
进行分隔,输出的内容之间默认以空格分开。
练习
练习1:华氏温度转换为摄氏温度。
提示:华氏温度到摄氏温度的转换公式为: C = ( F − 32 ) ÷ 1.8 C=(F - 32) \div 1.8 C=(F−32)÷1.8。
参考答案:
"""
将华氏温度转换为摄氏温度
Version: 0.1
"""
f = float(input('请输入华氏温度: '))
c = (f - 32) / 1.8
print('%.1f华氏度 = %.1f摄氏度' % (f, c))
:在使用
%.1f
是一个占位符,稍后会由一个float
类型的变量值替换掉它。同理,如果字符串中有%d
,后面可以用一个int
类型的变量值替换掉它,而%s
会被字符串的值替换掉。除了这种格式化字符串的方式外,还可以用下面的方式来格式化字符串,其中{f:.1f}
和{c:.1f}
可以先看成是{f}
和{c}
,表示输出时会用变量f
和变量c
的值替换掉这两个占位符,后面的:.1f
表示这是一个浮点数,小数点后保留1位有效数字。print(f'{f:.1f}华氏度 = {c:.1f}摄氏度')
练习2:输入圆的半径计算计算周长和面积。
参考答案:
"""
输入半径计算圆的周长和面积
Version: 0.1
"""
radius = float(input('请输入圆的半径: '))
perimeter = 2 * 3.1416 * radius
area = 3.1416 * radius * radius
print('周长: %.2f' % perimeter)
print('面积: %.2f' % area)
练习3:输入年份判断是不是闰年。
参考答案:
"""
输入年份 如果是闰年输出True 否则输出False
Version: 0.1
"""
year = int(input('请输入年份: '))
# 如果代码太长写成一行不便于阅读 可以使用\对代码进行折行
is_leap = year % 4 == 0 and year % 100 != 0 or \
year % 400 == 0
print(is_leap)
:比较运算符会产生布尔值,而逻辑运算符
and
和or
会对这些布尔值进行组合,最终也是得到一个布尔值,闰年输出True
,平年输出False
。