Bootstrap

【Python】基础语法(常量和表达式、变量和类型、注释、输入输出、运算符)

一、常量和表达式

我们可以把 Python 当成一个计算器,来进行一些算术运算。

注意 :print 是一个 Python 内置的 函数 。可以使用 + - * / ( ) 等运算符进行算术运算, 先算乘除, 后算加减。运算符和数字之间 可以没有空格, 也可以有多个空格。 但是一般习惯上写一个空格( 美观)。
  • 形如 1 + 2 - 3 这样是算式,在编程语言中称为表达式,算式的运算结果称为表达式的返回值。
  • 其中 1,2,3 这种称为字面值常量,+ - * / 这种称为运算符或者操作符。

注意 熟悉 C / Java 就可能会认为  2 / 3 结果为 0( 小数部分被截断), 但是在 Python 中得到的结果则是一个小数, 更符合日常使用的直觉。

给定四个分数:67.5、89.0、12.9、32.2,编写代码,求这四个分数的平均数。


二、变量和类型

1、变量是什么

有的时候,我们需要进行的计算可能更复杂一些,需要把一些计算的中间结果保存起来,这个时候就需要用到变量

给定四个分数:67.5、89.0、12.9、32.2,编写代码,求这四个分数的方差。

PS:方差的计算过程:取每一项,减去平均值(在后面的计算会被反复使用到),计算平方,再求和,最后再除以 (项数 - 1)

在这个代码中,就需要先计算这四个数字的平均值,然后再计算方差,这就需要把计算的平均值使用变量保存起来。就像计算器中的 M 键功能类似,通过变量就可以保存计算过程中的中间结果。

只不过,计算器一般只能保存一个数据,而在 Python 代码中,可以创建任意多的变量来随心所欲的保存很多很多的数据。

变量可以视为是一块能够容纳数据的空间这个空间往往对应到 “内存 这样的硬件设备上。

注意 avg、total、result 均为变量。
** 在 Python 中表示乘方运算, ** 2 即为求平方。

PS:可以把内存想像成是一个宿舍楼,这个宿舍楼上有很多的房间,每个房间都可以存放数据。

衡量内存的一个重要指标就是内存空间的大小,比如我的电脑内存是 16GB。这个数字越大,意味着内存的存储空间就越大,能够存放的数据(变量)就越多。


2、变量的语法

(1)定义变量

创建变量的语句非常简单, 其中:
  • a 变量名当我们创建很多个变量的时候,就可以用名字来进行区分。
  • = 赋值运算符表示把 = 右侧的数据放到 = 左侧的空间中。
注意 变量的名字要遵守一定规则。

A. 硬性规则(务必遵守)
  • 变量名必须由数字、字母、下划线构成,不能包含特殊符号。
  • 数字不能开头。
  • 变量名不能和 Python 的 “关键字”(在语法中有特定含义的)重复(比如:if、else等)。
  • 变量名大小写敏感,区分大小写。num Num 是两个不同的变量名。

B. 软性规则(建议遵守)
  • 变量名尽量使用有描述性的单词来表示,尽量通过名字表达出变量的作用。
  • 一个变量名可以由多个单词构成,变量名字长一点没有关系,但是变量的含义要清晰。
  • 当变量名包含多个单词的时候,建议使用 “驼峰命名法”(除了第一个单词的首字母以外,后续每个单词的首字母都要大写),形如 totalCount,personInfo 这种

数学上,变量通常使用 x,y,z 这种简单的英文字母或者拉丁字母表示,但是在编程中并不建议这样使用。是因为在编程中,一个程序里通常会同时创建出很多个变量。如果只是使用单个字母表示,在变量多了的时候,就很难记住每个变量对应的含义是什么,从而给维护程序带来了一定的困难,因此更建议使用带有明确描述性的名字来表示变量的用途。


(2)使用变量

A. 读取变量的值


B. 修改变量的值

注意 Python 中, 修改变量也是使用 = 运算, 看起来和定义变量没有明显区别。

当然,也可以用一个变量的值赋给另外一个变量:

首次使用 = 是对 a 进行设置值,这个过程是创建变量(初始化),后续再对 a 使用 = 操作,则是相当于修改 a 的内容赋值)。


3、变量的类型

变量里面存储的不仅仅是数字,还可以存储其它种类的数据。为了区分不同种类的数据引入了 “类型 这样的概念。

注意 C++ / Java 等语言不同, Python 变量的类型不需要显式指定 而只是依靠初始化语句,根据初始化的值的类型来进行确定的

(1)整数

type 和 print 类似,也是 python 内置的函数,可以使用 type 来查看一个变量的类型。

注意 C++ / Java 等语言不同,Python int 类型变量表示的数据范围是没有上限的。只要内存足够大,理论上就可以表示无限大小的数据。Python 的 int 可以根据要表示的数据的大小,自动扩容。所以,Python 就没有像 long 这样的类型,像 byte、short 这些类型也没有。 


(2)浮点数(小数)

注意 C++ / Java 等语言不同,Python 的小数只有 float 一种类型,没有 double 类型但实际上 Python 的 float 就相当于 C++ / Java double,表示双精度浮点数。

相比于单精度浮点数,双精度浮点数占用的内存空间更多,同时表示的数据精度更高即可(大概精确到小数点后 15 位)。


(3)字符串

Python 种没有字符类型,使用 ' ' 或者 " " 引起来的称为字符串可以用来表示文本。

注意 Python 中, 单引号构成的字符串和双引号构成的字符串, 没有区别, 'hello' "hello" 是 完全等价的。
如果字符串里面包含了双引号,表示字符串可以用单引号引起来;如果字符串里面包含了单引号,表示字符串可以用双引号引起来。
如果同时出现双引号或单引号呢?
Python 中还有一种字符串,使用 三引号(''' 或 """)表示。

可以使用 len 函数获取字符串的长度

可以使用 + 针对两个字符串进行拼接:

此处是两个字符串相加,也就是把后面的字符串拼接到前一个字符串的末尾,从而得到一个更大的字符串,对原先的 a1 和 a2 是没有影响的。

注意:不能把字符串和整数 / 浮点数进行相加。

在 Python 中,报错分以下两种情况:

  1. 语法错误。在程序运行之前,Python 解释器就能把错误识别出来。
  2. 运行错误。在程序运行之前无法识别,必须要执行到对应的代码才能发现问题。

(4)布尔

布尔类型是一个特殊的类型,取值只有两种:True(真) False(假)(首字母大写)。

布尔类型也是数学上的一个概念,数学上学过一个概念叫做 “命题”,进一步的就可以判定命题的真假。


(5)其他

除了上述类型之外, Python 中还有 list、tuple、dict、 自定义类型等等。

为什么要有这么多类型?
  • 类型决定了数据在内存中占据多大空间。例如:float 类型在内存中占据 8 个字节。

计算机里面使用二进制来表示数据,也就是每个位只能表示 0 或者 1。1 个二进制位就称为是一个个 “比特”,8 个二进制位,就称为一个 “字节”(Byte)。一个 float 变量在内存中占据 8 个字节空间,也就是 64 个二进制位。

假设电脑有 16GB 的内存空间,也就是一共有 1024 * 1024 * 1024 * 8 这么多的二进制位。

  • 不同的类型对应能够进行的操作也是不同的。
  1. int / float 类型的变量,可以进行 + - * / 等操作;
  2. str 类型的变量,只能进行 +(并且行为是字符串拼接),但是不能进行 - * /,能够使用 len 等其他操作。
总结 类型系统其实是在对变量进行  “ 归类”, 相同类型的变量( 数据) 往往具有类似的特性和使用规则。

4、动态类型特性

Python 中,一个变量是什么类型,是可以 “程序运行” 过程中发生变化的,这个特性称为 “动态类型

在程序执行过程中,a 的类型刚开始是 int,后面变成了 str,最后变成了 bool。

动态类型特性是一把双刃剑

  • 对于中小型程序,可以大大的节约代码量(比如写一段代码就可以同时支持多种类型)。
  • 对于大型程序,则提高了模块之间的交互成本(A 提供的代码难以被 B 理解)。

Python 作为一个动态类型的语言,在定义变量的时候,也可以是写类型的。

C++/Java 这样的语言则不允许这样的操作。一个变量定义后类型就是固定的了,这种特性则称为 “静态类型”。

一个编程语言是否是动态类型,只取决于运行时,类型是否发生改变,不取决于变量定义的时候是否声明类型。


三、注释

1、注释是什么

注释是一种特殊的代码,它不会影响到程序的执行,但是能够起到解释说明的作用,能够帮助程序猿理解程序代码的执行逻辑。

写代码是一件比较烧脑的事情,读代码同样也非常烧脑,相比于一板一眼的代码,一些口语化的描述能更好的帮助程序猿理解程序。

形如上述代码,如果没有注释直接阅读,是不容易体会到代码的含义是计算方差,但是如果通过加了一行注释解释一下,就可以让阅读代码的人一目了然了。

代码的第一目标是容易理解,第二目标才是执行正确

写注释不光是为了方便别人来理解,也是方便之后自己再阅读容易理解。


2、注释的语法

Python 中有两种风格的注释。

批量注释的快捷键:Ctrl + /


(1)注释行

使用 # 开头的行都是注释。

一般情况都是写在要注释的代码的上方,也有少数情况是写在要注释代码的右侧的,很少会写在代码的下方,不会写在代码的左侧。

# 这是一行注释

(2)文档字符串

使用三引号引起来的称为  “ 文档字符串 ”, 也可以视为是一种注释。
  • 可以包含多行内容,一般放在 文件 / 函数 类 的开头。
  • """ 或者 ''' 均可(二者等价)。
"""
这是文档字符串
这是文档字符串
"""

3、注释的规范

  1. 内容准确:注释内容要和代码一致且匹配,并在代码修改迭代时及时更新调整。
  2. 篇幅合理:注释既不要太精简,也不要长篇大论。
  3. 使用中文:一般中国的公司都要求使用中文写注释,外企另当别论。
  4. 积极向上:注释中不要包含负能量。

四、输入输出

1、和用户交互

程序需要和用户进行交互。

  • 用户把信息传递给程序的过程,称为 “输入”
  • 程序把结果展示给用户的过程,称为 “输出”

输入输出的最基本的方法就是控制台用户通过控制台输入一些字符串,程序再通过控制台打印出一些字符串。

PyCharm 运行程序,下方弹出的窗口就可以视为是控制台:

Windows 自带的 cmd 程序,也可以视为是控制台:

输入输出的最常见方法是图形化界面(常用)。如我们平时用到的 QQ,浏览器,steam 等,都不需要用户输入命令,而只是通过鼠标点击窗口点击按钮的方式来操作。


2、通过控制台输出

Python 使用 print 函数输出到控制台。

不仅能输出一个字符串,还可以输出一个其他类型的变量。

更多的时候,我们希望能够输出的内容是混合了字符串和变量的。示例输出 a = 10:

注意使用 f 作为前缀的字符串,f 表示 format,称为 f-string。里面可以使用 { } 来内嵌一个其他的变量 / 表达式。Python 中还支持其他的格式化字符串的方法。


3、通过控制台输入

python 使用 input 函数,从控制台读取用户的输入:

input 执行的时候就会等待用户输入,这个等待可能是一个非常长的等待,完全取决于用户什么时候去输入。如果用户始终不输入,那么就会一直等待。

注意input 的参数相当于一个 “提示信息”,也可以没有。

input 的返回值就是用户输入的内容,字符串类型。

如果只是单纯的拿到用户的输入,然后进行打印,那么此时就按照 str 打印即可。如果需要根据用户输入的内容进行算术计算,那么此时就需要先把读到的 str -> int,可以使用 int()。

此处的结果是字符串拼接,不是算术运算。如果要想进行算术运算,需要先转换类型。

通过 int( ) 把变量转成了 int 类型。

使用 float( )(将字符串转换成浮点数)、bool( ),str( )(将整数转换成字符串)等可以完成对应的类型转换。

代码示例:输入 4 个小数,求 4 个小数的平均值。


五、运算符

1、算术运算符

+ - * / % ** // 这种进行算术运算的运算符,称为算术运算符

注意:/ 中不能用 0 作为除数,否则会抛出异常

有些编程语言中,/ 整数 0 会抛出异常,/ 浮点数 0 会得到无穷大,而在 Python 中则都认为是除 0 异常。 

异常是编程语言中的一种常见机制,表示程序运行过程中,出现了一些 “意外情况”,导致程序不能继续往下执行了。

先算乘方,再算乘除,最后算加减。如果在运算过程中想要修改默认的运算顺序,就需要加上()。

注意 整数 / 整数 结果可能是小数,而不会截断。

关于求余数:7 除以 2,商是 3,余数是 1。

% 不是 “百分数”,而是求余数。得到的余数一定是小于除数的。

** 是求乘方。既能算整数次方,还能算小数次方(开方运算)。

// 是取整除法(也叫地板除)。整数除以整数,结果还是整数(舍弃小数部分,并向下取整,不是四舍五入)。


2、关系运算符

< <= > >= == != 这一系列的运算符称为 关系运算符 它们是在比较操作数之间的 “大小”、“相等” 关系。其中:
  • <=  “小于等于”
  • >=  “大于等于”
  • ==  “等于”
  • !=  “不等于”

(1)关系运算符对应的表达式的值是布尔类型

如果关系符合要求,则表达式返回 True;如果关系不符合要求,则表达式返回 False。


(2)关系运算符不光针对整数 / 浮点数进行比较,还能针对字符串进行比较

注意 直接使用 == 或者 != 即可对字符串内容判定相等( 这一点和 C / Java 不同)。 字符串比较大小, 规则是  “ 字典序
关于字典序:想象一个英文词典,上面的单词都是按照字母顺序排列。如果首个字母相同,就比较第二个字母(就比如著名单词 abandon)。认为一个单词在词典上越靠前就越小,越靠后就越大。

针对中文进行字符串大小的比较是没有意义的,至少按照默认的字典序来说是没有意义的。在计算机中表示中文,其实是多个字节构成的一个比较大的数字来进行比较。

  • 在 C/C++ 中,strcmp,如果直接使用 ==,本质上是在比较两个字符串首元素的地址。
  • 在 Java 中,equals 方法,如果使用 ==,本质上是在比较这两个字符串是否为同一个对象。

Python 是直接使用 == 和 != 来比较字符串内容相同,这是大部分编程语言遵守的规则。


(3)对于浮点数来说,不要使用 == 判定相等

注意 浮点数在计算机中的表示并不是精确的,因为浮点数在内存中的存储和表示是可能存在误差的。这样的误差在进行运算过程中就可能被放大,从而导致出现误判

可以看到,0.1 + 0.2 的结果并非是 0.3,虽然这两个数字已经非常接近了,但是如果使用 == 进行比较,仍然会导致 == 的结果为 False。

不止是 Python 如此,主流编程语言都是如此。这个是 IEEE754 标准规定的浮点数格式所引入的问题。

正确的比较方式不再严格比较相等了,而是判定差值小于允许的误差范围。

在 Python 中支持这种连续小于的写法,判断 a-b 既是 > -0.000001 又是 < 0.000001。

实际工程实践中,误差在所难免,只要保证误差在合理范围内即可。


3、逻辑运算符

and or not 这一系列的运算符称为逻辑运算符

  • and:并且,两侧操作数均为 True,最终结果为 True,否则为 False(一假则假)
  • or:或者,两侧操作数均为 False,最终结果为 False,否则为 True(一真则真)
  • not:逻辑取反,操作数本身为 True,则返回 False,本身为 False,则返回 True。

此处说的 “并且” 和 “或者”,就是平时日常生活中使用的 “并且” 和 “或者”。

(1)一种特殊的写法

a < b and b < c 这个操作等价于 a < b < c

(2)短路求值

Python 也存在短路求值的规则:
  • 对于 and,如果左侧表达式为 False,则整体一定为 False,右侧表达式不再执行。
  • 对于 or,如果左侧表达式为 True,则整体一定为 True,右侧表达式不再执行。

上述代码没有抛出异常,说明右侧的除以 0 操作没有真正执行。


4、赋值运算符

(1)= 的使用

= 表示赋值,已经用过很多次了,注意和 == 做区分。

= 除了基本的用法之外,还可以同时针对多个变量进行赋值。


A. 链式赋值
a = b = 10

# 先把 10 赋值给 b
# 再把 b 赋值给 a

一般不建议使用链式赋值,尽量一行代码只是包含一个操作。 


B. 多元赋值
a, b = 10, 20

# 把 10 赋值给 a
# 把 20 赋值给 b

交换两个变量:

基于多元赋值:


(2)复合赋值运算符

Python 还有一些 复合赋值运算符例如 += -= *= /= %=。

其中 a += 1 等价于 a = a + 1,其他复合赋值运算符也是同理。

注意 C++ / Java 中, 存在 ++ -- 这样的自增  自减运算符, Python 中则不支持这种运算。 如果需要使用,则直接使用 += 1 或者 - = 1。

++ 和 -- 最大的问题就是容易分不清前置和后置的区别,这一点 Python 语法在设计的时候就进行了规避,避免出现这种不直观,并且容易混淆的语法。


5、其他

除了上述之外,Python 中还有一些运算符,比如身份运算符is,is not),成员运算符in,not in),位运算符(& | ~ ^ << >>)等,这里暂时不做介绍。

;