Python基础知识
1 模块¶
1.1 安装¶
利用python内置的pip工具安装,可在命令行中使用
命令为:pip install 模块名
1.2 导入与使用¶
import关键字导入,格式如下:
import 模块1,模块2,...
模块导入后使用“.”调用模块中内容,格式如下:
模块.函数
模块.变量
[!tip]
通过点字符调用模块中的内容可避免多个模块中存在同名函数时代码产生歧义,但若不存在同名函数,可使用from...import...语句直接将模块的指定内容导入程序,并在程序中直接使用模块中的内容。
例如将pygame模块的init()函数导入程序,并直接使用该函数,具体代码如下:
1 2 |
|
使用from...import...语句也可将指定模块的全部内容导入当前程序,此时可使用“”指代模块中的全部内容,虽然from...import * 可以方便地导入一个模块中的所有内容,但考虑到代码的可维护性,此种方式不应被过多地使用*。
例如将pygame模块的init()函数导入程序,并直接使用该函数,具体代码如下:
1 |
|
2 良好的代码格式¶
2.1 注释¶
2.1.1 单行注释¶
以“#”开头,用于说明当前行或之后代码,独占一行或位于标识代码之后
2.1.2 多行注释¶
由三对双引号或者单引号包裹的语句,主要用于说明函数或类的功能,如:
1 2 3 |
|
2.2 语句换行¶
Python官方建议每行代码不超过79个字符,若代码过长应该换行。Python会将圆括号、中括号和大括号中的行进行隐式连接,我们可以根据这个特点实现过长语句的换行显示,如:
1 2 3 4 |
|
3 标识符和关键字¶
3.1 标识符¶
若希望在程序中表示一些事物,开发人员需要自定义一些符号和名称,这些符号和名称叫做标识符。规则如下:
- 标示符由字母、下划线和数字组成,且数字不能开头。
- Python中的标识符是区分大小写的。例如,andy和Andy是不同的标识符。
- Python中的标识符不能使用关键字 。
为了规范命名标识符,关于标识符的命名提以下建议:
- 见名知意
- 常量名使用大写的单个单词或由下画线连接的多个单词模块名、函数名使用小写的单个单词或由下画线连接的多个单词;类名使用大写字母开头的单个或多个单词。
3.2 关键字¶
关键字是Python已经使用的、不允许开发人员重复定义的标识符。Python3中一共有35个关键字,每个关键字都有不同的作用。在spyder单元格中执行help("keywords")
可查看关键字的声明。
4 变量和数据类型¶
4.1 变量的输入与输出¶
4.1.1 输入¶
用 input()
函数,返回值类型为字符串
[!tip]
多变量输入:.split()
1
name, age = input("请输入你的名字和年龄,用空格分隔: ").split()
4.1.2 输出¶
4.1.2.1 基础输出¶
print(\*objects, sep=' ', end='\n', file=sys.stdout)
-
objects
:表示输出的对象。输出多个对象时,对象之间需要用分隔符分隔。 -
sep
:用于设定分隔符,默认使用空格作为分隔。 -
end
:用于设定输出以什么结尾,默认值为换行符\n。 -
file
:表示数据输出的文件对象。
4.1.2.2 格式化输出¶
4.1.2.2.1 方式一:格式符输出¶
格式符号 | 转换 |
---|---|
%c |
字符 |
%s |
通过 str() 字符串转换来格式化 |
%i |
有符号十进制整数 |
%d |
有符号十进制整数 |
%u |
无符号十进制整数 |
%o |
八进制整数 |
%x |
十六进制整数(小写字母) |
%X |
十六进制整数(大写字母) |
%e |
索引符号(小写'e') |
%E |
索引符号(大写"E") |
%f |
浮点实数 |
%g |
%f 和 %e 的简写 |
%G |
%f 和 %E 的简写 |
示例代码:
1 2 3 |
|
4.1.2.2.2 方式二:f-string¶
示例:
1 |
|
在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:
1 2 3 |
|
4.1.2.2.3 方式三:.format()
方法¶
.format()
方法是一种在Python中用于字符串格式化的机制。它提供了一种灵活的方式来插入变量值到字符串中,并且支持多种格式化选项。以下是.format()
方法的一些基本用法和特点:
基本用法¶
1 2 3 4 5# 使用位置参数 print("Hello, {0}. You are {1} years old.".format("Alice", 30)) # 使用关键字参数 print("Hello, {name}. You are {age} years old.".format(name="Alice", age=30))
格式化选项¶
.format()
方法允许你指定各种格式化选项,例如:
- 对齐方式:
<
(左对齐)、>
(右对齐)、^
(居中对齐)- 宽度:指定字段的最小宽度
- 精度:对于浮点数,指定小数点后的位数;对于整数,指定显示的位数
- 填充字符:指定用于填充的字符
1 2 3 4 5 6 7 8 9 10 11# 对齐方式和宽度 print("{:<10}".format("left")) # 左对齐,宽度为10 print("{:>10}".format("right")) # 右对齐,宽度为10 print("{:^10}".format("center"))# 居中对齐,宽度为10 # 精度 print("{:.2f}".format(3.14159)) # 浮点数,保留两位小数 print("{:.3g}".format(123456)) # 整数,保留三位有效数字 # 填充字符 print("{:\*^10}".format("fill")) # 使用\*作为填充字符,居中对齐,宽度为10
索引和属性¶
.format()
方法还可以用于访问对象的属性或字典的键:
1 2 3 4 5 6 7 8 9 10 11class Person: def __init__(self, name, age): self.name = name self.age = age p = Person("Bob", 25) print("Hello, {0.name}. You are {0.age} years old.".format(p)) # 对于字典 person_dict = {"name": "Bob", "age": 25} print("Hello, {name}. You are {age} years old.".format(**person_dict))
性能¶
虽然
.format()
方法非常灵活,但它可能比f-string稍慢,特别是在需要频繁格式化大量字符串的场景中。因此,在性能敏感的应用中,使用f-string可能是更好的选择。总的来说,
.format()
方法提供了一种强大且灵活的方式来格式化字符串,支持多种格式化选项和复杂的数据结构。它是在Python 2和Python 3中都可用的格式化方法,但在Python 3中,f-string通常是首选,因为它更简洁、易读且执行效率更高。
几个示例:
数字 | 格式 | 输出 | 描述 |
---|---|---|---|
3.1415926 | {:.2f} |
3.14 | 保留小数点后两位 |
3.1415926 | {:+.2f} |
+3.14 | 带符号保留小数点后两位 |
-1 | {:+.2f} |
-1.00 | 带符号保留小数点后两位 |
2.71828 | {:.0f} |
3 | 不带小数 |
5 | {:0>2d} |
05 | 数字补零(填充左边,宽度为2) |
5 | {:x<4d} |
5xxx | 数字补x(填充右边,宽度为4) |
10 | {:x<4d} |
10xx | 数字补x(填充右边,宽度为4) |
1000000 | {:} |
1,000,000 | 以逗号分隔的数字格式 |
0.25 | {:.2%} |
25.00% | 百分比格式 |
1000000000 | {:.2e} |
1.00e+09 | 指数记法 |
13 | {:10d} |
13 | 右对齐(默认,宽度为10) |
13 | {:<10d} |
13 | 左对齐(宽度为10) |
13 | {:^10d} |
13 | 中间对齐(宽度为10) |
11 | '{:b}'.format(11) |
1011 | 二进制 |
11 | '{:d}'.format(11) |
11 | 十进制 |
11 | '{:o}'.format(11) |
13 | 八进制 |
11 | '{:x}'.format(11) |
b | 十六进制 |
11 | '{:#x}'.format(11) |
0xb | 0x开头十六进制 |
11 | '{:#X}'.format(11) |
0XB | 0X开头十六进制 |
^
<
>
分别是居中、左对齐、右对齐,后面带宽度。
:
号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。
+
表示在正数前显示 +
,负数前显示 -
。
(空格)表示在正数前加空格。
b
d
o
x
分别是二进制、十进制、八进制、十六进制。
此外我们可以使用大括号 {}
来转义大括号,如输入 {{}}
会输出 {}
。
4.1.2.2.4 ==保留有效数字方式==¶
4.1.2.2.4.1 使用字符串格式化(format()
方法)¶
可以使用format()
方法中的g
或G
格式说明符来保留有效数字。这种方法会自动根据数值的大小选择固定点或科学计数法表示,并保留指定的有效数字位数。
1 2 3 |
|
4.1.2.2.4.2 使用f-string(Python 3.6+)¶
f-string提供了一种更简洁的方式来进行字符串格式化,包括保留有效数字。
1 2 3 |
|
4.1.2.2.4.3 使用round()
函数¶
如果你只需要简单地四舍五入到指定的小数位数,可以使用round()
函数。但请注意,round()
函数保留的是指定的小数位数,而不是有效数字。
1 2 3 |
|
[!tip]
round()
函数效果是四舍五入到指定的小数位数
round()
函数只是保留到制定的小数位数,而不是有效数字
4.1.2.2.4.4 使用decimal
模块¶
对于需要高精度的金融或科学计算,可以使用decimal
模块,它提供了更多的控制,包括保留有效数字。
1 2 3 4 5 |
|
4.1.2.3 转义字符¶
转义字符 | 描述 | 实例 |
---|---|---|
(在行尾时) | 续行符 | >>> print("line1 \ ... line2 \ ... line3") line1 line2 line3 >>> |
\ | 反斜杠符号 | >>> print("\") | |
\' | 单引号 | >>> print('\'') ' |
\" | 双引号 | >>> print("\"") " |
\a | 响铃 | >>> print("\a") 执行后电脑有响声。 |
\b | 退格(Backspace) | >>> print("Hello \b World!") Hello World! |
\000 | 空 | >>> print("\000") >>> |
\n | 换行 | >>> print("\n") >>> |
\v | 纵向制表符 | >>> print("Hello \v World!") Hello World! >>> |
\t | 横向制表符 | >>> print("Hello \t World!") Hello World! >>> |
\r | 回车,将 \r 后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将 \r 后面的内容完全替换完成。 | >>> print("Hello\rWorld!") World! >>> print('google runoob taobao\r123456') 123456 runoob taobao |
\f | 换页 | >>> print("Hello \f World!") Hello World! >>> |
\yyy | 八进制数,y 代表 0~7 的字符,例如:\012 代表换行。 | >>> print("\110\145\154\154\157\40\127\157\162\154\144\41") Hello World! |
\xyy | 十六进制数,以 \x 开头,y 代表的字符,例如:\x0a 代表换行 | >>> print("\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21") Hello World! |
\other | 其它的字符以普通格式输出 |
4.2 变量的实质¶
4.2.1 变量的内存分配¶
当我们同样创建一个变量a并给他赋值,内存会分配两个空间,一个空间存放这个值,另一个空间才是a真正的归宿,而a中存储的是这个值所在空间的地址,换个说法即a指向这个值所在空间。再换个亲切的说法,这其实就类似于C语言中的指针。
两个帮助你搞清 Python 内存分配机制的技巧:
- 我们可以通过
id
函数来查看变量的“编号”(实际上是内存地址)。 - 我们可以使用
is
运算符来判断两个变量是否引用同一个对象——这个很常用。
1 2 3 4 5l1 = [1, 2, 3] # 现在我们定义一个列表 l2 = l1 # 将l1的内容赋给新变量l2 l2[2] = 4 # 改变l2中下标为2的元素 print(f'l1={l1}, l2={l2}') # 发现l1[2]的值也变了,为啥?
1
l1=[1, 2, 4], l2=[1, 2, 4]
那么来探究一下 Python 中变量的底层逻辑。
1 2 3 4 5 6 7 8 9a = 5 # 当我们定义一个变量a=5时,Python 会在电脑中寻找一块内存,把5写入这块内存,然后将a指向这块内存。 print(id(a)) a = 6 # 当我们将a的值改成6时,Python 会开辟一块新的内存,然后把6写入这块内存,接着让a转而指向这块内存。 print(id(a)) b = 6 # 定义一个同样为6的变量b,你会发现b指向的内存和a是同一块。 print(id(b)) print(a is b) # 事实上,a和b就是引用同一个对象的不同“别名” a = 5 print(id(a)) # 把a改回5,发现其指回了之前那一块内存,其中的内容没有变化,仍然是5
1 2 3 4 5140727755916200 140727755916232 140727755916232 True 140727755916200
上面这个例子实际上解释了两个问题:
- 因为给同一个变量赋不同的值时,Python 都会“另起炉灶”——开辟一块新的内存来存储新值,所以我们可以随时改变一个变量的数据类型而不用担心不同数据类型占用空间大小不同引起的危险。
虽然Python 中可以任意改变变量的数据类型,但在实际开发中这是非常不好的操作,应该保证一个确定的变量在整个生命周期中为同一个确定的数据类型。
- 因为给一个int、float、str、tuple类型的变量赋新值并不会改变原来那块内存中存储的值,所以说他们是不可变类型。
不可变类型的实质:
- 只要变量的值改变,地址也跟着改变。
- 常见的不可变类型:int、float、str、tuple
例如:
1 2 3 4 5 |
|
1 2 3 |
|
可变类型 的实质:
-
变量的内容改变时,地址不变,即可以对原地址中的值进行修改。
-
常见的可变类型 :list、set、dict
定义一个list类型时,系统会申请一段固定长度地址空间存放list,所以当需要添加删除元素时,只需要在申请好的内存空间内操作即可,地址不发生改变。
例如:
1 2 3 4 5 |
|
1 2 |
|
对可变类型 的变量进行复制时,需要注意区分引用、 浅拷贝 和 深拷贝。
- 引用:使用
=
直接赋值,不仅复制了对象的内容,也复制了其内存地址。两者互相关联,互相影响。 - 浅拷贝:增加一个指向某个对象的地址,而不复制对象本身,新对象和原对象共享一块内存。
- 深拷贝:增加一个指向某个对象的地址并且申请一片新内存,新对象和原对象并不共享内存,二者没有任何关联也不会互相影响。
其中浅拷贝和深拷贝的区别在嵌套的可变类型对象中才会体现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
1 2 3 4 |
|
4.3 数据类型¶
4.2 字符串类型¶
格式化输出:[[Python基础知识#2.3.3.2.2 格式化输出]]
速查网站:菜鸟教程-Python字符串
4.3 列表类型(list)¶
4.3.1 创建列表¶
- 创建空列表:
a = []
或a = list()
4.3.2 添加列表元素¶
-
列表类型的变量可以通过
append
方法在末尾添加新的元素。- 例如
a.append(4)
表示在列表a
的末尾添加一个元素4
。 -
添加多个元素可以通过
extend
方法。 -
例如
a.extend([5, 6, 7])
表示在列表a
的末尾添加三个元素5、6、7
。 - 可以通过
insert
方法在列表任意位置插入元素。
- 例如
4.3.3 删除列表元素¶
-
列表类型的变量可以通过
pop
方法删除指定位置的元素。- 例如
a.pop(2)
表示删除列表a
中的索引为2
的元素,并将这个数返回。 - 如果不填入参数则默认删除列表末尾最后一个元素。
- 可以通过
remove
方法删除指定的元素。
- 例如
4.3.4 列表访问¶
- 列表索引
-
列表切片
a[start, end, step]
- 切片遵循左开右闭原则,即 \([start,step)\)
4.3.5 列表分割和拼接¶
-
列表分割:
-
split
方法,可以将字符串按照指定的字符分割成若干部分 - 例如
'1,2,3'.split(',')
表示将字符串'1,2,3'
按照逗号,
分割成若干部分,然后拼接成列表。 -
列表拼接:
-
join
方法,可以将多个字符按照指定的分隔符拼接成字符串。 - 例如
'-'.join([1, 2, 3])
表示将列表[1,2,3]'
按照减号-
拼接成一个字符串。
-
4.4 元组类型(tuple)¶
- 类似列表的类型,但是不可修改
- 使用元组来存储一些执行过程中不需要变化的数据能大大提高程序性能
4.4.1 创建元组¶
-
a = ()
或a = tuple()
(后者可读性更强) - 创建只有一个元素的元组:使用
a = (1,)
而不是a = (1)
,后者括号会被识别为运算符
4.5 集合类型(set)¶
4.5.1 创建集合以及集合的性质¶
Python 中的集合类型用来表示一组互不相同的数据,类似于数学中的集合。集合类型的变量用花括号 {}
括起来,其中的每个元素用逗号 ,
隔开,例如 {1, 2, 3}
。
回忆一下数学中集合的性质:确定性、无序性、唯一性。
后面两个特性也是Python 集合最重要的特性。
- 无序性:无法通过索引取值。
- 唯一性:添加已存在的元素不会生效。
4.5.2 集合的运算¶
集合的运算包括并集、交集、差集等等
- 例如
a | b
表示集合a
和集合b
的并集 -
a & b
表示集合a
和集合b
的交集 -
a - b
表示集合a
和集合b
的差集 -
a ^ b
表示集合a
和集合b
的对称差(即a | b
减去a & b
)。
4.5.3 添加与删除集合元素¶
集合类型的变量可以通过 add
方法添加新的元素,例如 a.add(4)
表示在集合 a
中添加一个元素 4
。
集合类型的变量可以通过 remove
方法删除元素,例如 a.remove(4)
表示删除集合 a
中的元素 4
。
集合的 update
方法,可以根据输入的另一集合智能地更新集合中的元素。
因为特殊的存储原理,集合的元素必须是可哈希的值(即不可变的对象)。而列表、集合、字典都是可变对象,因此不可哈希,不能作为集合的元素。
4.6 字典类型(dict)¶
Python 中的字典类型用来表示一组键(key)值(value)对。字典类型的变量用花括号 {}
括起来,其中的每个键值对用逗号 , 隔开,每个键值对的键和值用冒号 :
隔开,例如 {'a': 1, 'b': 2, 'c': 3}
。
字典中的元素是无序的,可以通过键来访问其中的值,例如 a['a']
表示字典 a
中键为 'a'
的值,a['b']
表示字典 a
中键为 'b'
的值,以此类推。
在同一个字典中,键(key)必须是唯一的;如果一个 key 出现两次,后面的赋值会覆盖掉前面的。
字典的键(key)必须使用不可变类型,如数字、字符串、元组。而字典的值(value)可以是任意类型,包括字典类型本身。
和集合一样,字典也可以使用 update
方法来更新元素。
字典还有一个通过键来获取值的方法 get
。与通过中括号 [key]
来获取值相比,get
方法在输入不存在的键时不会报错,并且可以自定义键不存在时的返回值。
4.7 空类型(None)¶
Python 中的 None 类型用来表示空值。
None是Python中的一个内置对象,表示空值或空类型。它不等于任何其他对象,包括空字符串、空列表或零。使用None作为变量的初始值,可以明确表达该变量目前没有绑定任何值。
4.8 数据类型相互转换¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 |
|
5 数字类型¶
5.1 整型¶
5.1.1 计数方式¶
- 二进制 0B或0b开头
- 八进制 0o或0O开头
- 十六进制 0x或0X
5.1.2 转换数据¶
1 2 3 4 |
|
5.2 浮点型¶
浮点型(float)用于表示实数,由整数和小数部分(可以是0)组成例如,3.14、0.9等。较大或较小的浮点数可以使用科学计算法表示。
科学计数法会把一个数表示成a与10的n次幂相乘的形式,数学中科学计数法的格式为:
Python程序中省略“×”,使用字母e或E代表底数10,示例如下:
- -3.14e2 # 即-314
- 3.14e-3 # 即0.00314
Python中的浮点型每个浮点型数据占8个字节(即64位),且遵守 IEEE 标准。Python 中浮点型的取值范围为 -1.8e308~1.8e308,若超出这个范围,Python 会将值视为无穷大(inf)或无穷小(-inf)。
有关浮点数在计算机中的存储(IEEE 标准)参见[[Python数据类型二进制表示]]
5.3 复数类型¶
复数由实部和虚部构成,它的一般形式为:real+imagj,其中real为实部,imag为虚部,j为虚部单位。示例如下:
- complex_one = 1 + 2j # 实部为1,虚部为2
- complex_two = 2j # 实部为0,虚部为2
通过real和imag属性可以获取复数的实部部分和虚部部分。
1 2complex_one.real complex_one.imag
5.4 布尔类型¶
Python中的布尔类型只有True(真)和False(假)两个取值。实际上,布尔类型也是一种特殊的整型,其值True对应整数1,False对应整数0。
若数据符合以下任一条件,其布尔值均为False。
- 值为None或False的常量
- 任何数字类型的0:0、0.0、0j
- 空组合数据类型:''、()、[]、set()、{}
5.5 数字类型转换¶
6 类型注解¶
Python 3.5 引入了类型注解,可以为变量、函数参数和返回值添加类型提示,可以提高代码的可读性和可维护性。
类型注解的语法是在对应的变量或参数名后面加上冒号和类型。对于函数返回值,是在函数定义的末尾加上箭头->和类型。
1 2 3 4 5 6 7 8 9 10 11 |
|
值得注意的是,作为动态语言,Python中变量的数据类型是可变的,因此类型注解并不具备强制性。你依然可以给一个注解为int类的变量赋值一个字符串,这不会产生任何报错,但这会破坏代码的可读性。
类型注解的意义是让我们一眼就能看出变量或者函数参数的数据类型,同时也能让IDE能够提供更好的代码提示和代码检查。将鼠标指针悬停在具有类型注解的变量或函数参数上,可以看到变量或参数的类型提示。
此外,在定义函数的时候,你可以先写一段多行注释来介绍该函数的功能和参数,在函数中首次出现的多行注释会在鼠标悬停在函数名上时出现在介绍文档中。
此外,对于一个变量或参数,可以注解多个类型,用 |
分隔。
1 2 3 4 |
|