Python基础语法总结

关于Python3的编码规范、基础语法、数据类型进行总结,需要有其他编程语言的基础

编码规范

编码过程中需要注意的地方

命名规范

  • 第一个字符必须是字母或下划线

    但是以下划线开头通常有特殊意义(单下划线开头代表禁止外部访问的成员,双下划线开头代表类的私有成员,前后都双下划线的是Python里特殊方法的标识,如__init__代表类的构造函数),所以一般情况命名就是以字母开头

  • 其他部分由字母、数字和下划线组成

    例如:a&bhello-ph@a都不行

  • 变量名全小写,常量名全大写

  • 函数和方法名用小写+下划线

  • 类名用驼峰

  • 模块和包的名字都用小写

    所谓模块就是.py文件,所谓包就是一个文件夹,有一个__init__.py文件,这个文件夹就是一个python包

注释

注释这里只有两种形式,一种是#后跟说明文字,一种是""" ... """用三个双引号标起来的,是可以被识别的文档注释,但是这三个双引号必须是在类或方法定义的下一行

注意:行尾注释的话,必须在代码后面两个空格加#,并且#后还必须加一个空格,再往后才可以写文字,不过一般IDE会自动检查格式

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def print_hi(name):
"""
这个方法的作用就是向传进来的name说Hi

:param name: 名字
:return: void
"""
print(f'Hi, {name}')


class Foo:
"""
随便定义了一个类
"""

def __init__(self, name):
self.name = name


if __name__ == '__main__':
foo = Foo("sunny")
print_hi(foo.name) # 执行print_hi方法

鼠标放到类或方法上都会有相应的文档提示:

image-20211113151823542 image-20211113151838195

代码块

Python中具有相同缩进的代码,就认为处在一个代码块中,Python中不用{}花括号来标识代码块了,这是个需要注意的地方

Python推荐用四个空格来表示一次缩进

空白行和空白字符

  • 定义函数,一个函数的上方,应该留一个空行,也就是一个空白行
  • 定义类,类的上方,应该留两个空行,也就是两行空白
  • 变量赋值,=左右各留一个空格

编码

Python3在运行时全部使用Unicode编码!

Python中的字符串

在Python中,只要是用引号包起来的就是字符串,不管是双引号还是单引号,都是字符串

基础语法

Python中的变量

牢记一句话:在Python中,一切皆是对象,所谓变量只是指针

  • 变量不用声明类型,但是必须得赋值,赋值后变量才会被创建

    不用声明类型,一切皆对象,只是把a的指向改变了

    1
    2
    3
    4
    if __name__ == '__main__':
    a = "hello world!"
    a = 666
    print(a)
  • 允许同时给多个变量赋值

    1
    a, b, c = 1, 2, 3

运算符

Python语言支持以下类型的运算符:

  • 算术运算符
  • 比较(关系)运算符
  • 赋值运算符
  • 逻辑运算符
  • 位运算符
  • 成员运算符
  • 身份运算符
  • 三目运算符

这里只说Python与Java不同的地方

逻辑运算符

在Python中,没有用&&||!来表示且或非的关系,Python中使用英文单词andornot来表示且或非

成员运算符

这个是Python独有的,是innot in,来表示对象是否是某个集合的元素之一,运行速度也很快,返回的结果值是布尔类型(True换和False)

1
2
3
4
5
6
7
8
if __name__ == '__main__':
res_list = [1, 2, 3]
a = 1
print(a in res_list)
print(a not in res_list)
# 结果
True
False

身份运算符

也是Python独有的,isis not,用来判断两个标识符是否引用自同一个对象

1
2
3
4
5
6
7
8
9
10
if __name__ == '__main__':
res_list = [1, 2, 3]
a = 1
a = res_list
print(res_list is a)
a = [1, 2, 3]
print(res_list is a)
# 运行结果
True
False

三目运算符

Java是这种这种形式:boolean result = a > b ? true : false

判断a > b 就返回true,不大于就返回false

Python中三目运算符不是这种,而是 为真时的结果 if 判定条件 else 为假时的结果

1
2
3
4
5
6
if __name__ == '__main__':
a, b = 1, 2
result = True if a > b else False
print(result)
# 运行结果
False

数据类型

Python中数据类型分两种,一种是内置的,一种是自定义的

内置的包括数字、字符串、布尔、列表、元组、字典、Bytes、集合这些常用的以及一些不太常用的数据类型。而自定义的,一般以类的形式,根据需要组合以上内置类型成为独特的数据类型。

数字类型

Python支持整数、浮点数和复数

  • 整数(int):没有长整型和短整型之分,统称为整型,长度为32位,这个里面的整型可以当作Long型使用

  • 浮点数(float):浮点数也就是小数,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,一般用科学计数法表示,把10用e替代,1.23x10^9就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。

  • 复数( (complex)):复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示,复数的实部a和虚部b都是浮点型。关于复数,不做科学计算或其它特殊需要,通常很难遇到。

  • 数字类型转换:

    int(x): 将x转换为一个整数。如果x是个浮点数,则截取小数部分。

    float(x) :将x转换到一个浮点数。

    complex(x) :将x转换到一个复数,实数部分为 x,虚数部分为 0。

    complex(x, y): 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y

空值和布尔类型

  • 空值:在Python中空值是用None来表示,首字母大写,它的数据类型是NoneType,是一个独有的。没有null这一说
  • 布尔类型:TrueFalse注意首字母大写

列表

最常用的数据结构之一了,方括号括起来就是列表

python中的列表可以放任意的数据类型,可以多层嵌套列表,各种数据类型都可以往列表里面放

基本操作

  • 创建列表

    1
    2
    my_list = []  # 空列表
    my_list = [1, 'a', [1, 'b'], 'hello', 6] # 包容各种数据类型,支持嵌套
  • 删除元素

    1
    2
    3
    4
    5
    6
    if __name__ == '__main__':
    my_list = [1, 'a', [1, 'b'], 'hello', 6] # 包容各种数据类型,支持嵌套
    del my_list[0]
    print(my_list)
    # 运行结果
    ['a', [1, 'b'], 'hello', 6]
  • 修改元素

    直接赋值就行

    1
    2
    3
    4
    5
    6
    if __name__ == '__main__':
    my_list = [1, 'a', [1, 'b'], 'hello', 6] # 包容各种数据类型,支持嵌套
    my_list[0] = 666
    print(my_list)
    # 运行结果
    [666, 'a', [1, 'b'], 'hello', 6]
  • 获取元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if __name__ == '__main__':
    my_list = [1, 'a', [1, 'b'], 'hello', 6] # 包容各种数据类型,支持嵌套
    print(my_list[0]) # 获取单个元素
    # 遍历
    for e in my_list:
    print(e)
    # 通过下标遍历
    for i in range(len(my_list)):
    print(my_list[i])

特殊操作和常用函数

注意:求最大最小值函数,当列表中数据类型有各种类型的时候不能求最值

语句结果描述
[1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]组合两个列表
[‘Hi!’] * 4[‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’]列表的乘法
3 in [1, 2, 3]True判断元素是否存在于列表中
for x in [1, 2, 3]: print x,1 2 3迭代列表中的每个元素
函数作用
len(list)返回列表元素个数,也就是获取列表长度
max(list)返回列表元素最大值
min(list)返回列表元素最小值
list(seq)将序列转换为列表

切片

语法:list[start:end]

以冒号分割索引,start代表起点索引,end代表结束点索引。省略start表示以0开始,省略end表示到列表的结尾。注意,区间是左闭右开的!也就是说[1:4]会截取列表的索引为1/2/3的3个元素,不会截取索引为4的元素。分片不会修改原有的列表,可以将结果保存到新的变量,因此切片也是一种安全操作,常被用来复制一个列表,例如newlist = lis[:]

如果提供的是负整数下标,则从列表的最后开始往头部查找。例如-1表示最后一个元素,-3表示倒数第三个元素。

切片过程中还可以设置步长,以第二个冒号分割,例如list[3:9:2],表示每隔多少距离取一个元素。

列表内置方法[要熟记于心]

方法作用
append(obj)在列表末尾添加新的对象
count(obj)统计某个元素在列表中出现的次数
extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
index(obj)从列表中找出某个值第一个匹配项的索引位置
insert(index, obj)将对象插入列表
pop(obj=list[-1])移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
remove(obj)移除列表中某个值的第一个匹配项
reverse()反向列表中元素
sort([func])对原列表进行排序
copy()复制列表
clear()清空列表,等于del lis[:]

可以将列表当作栈来使用

1
2
3
4
5
6
7
8
9
if __name__ == '__main__':
stack = [1, 2, 3, 4, 5, 6] # 栈从栈底到栈顶依次是 1 2 3 4 5 6
stack.pop() # 弹出栈顶元素
print(stack)
stack.append(8) # 把8压入栈
print(stack)
# 运行结果
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 8]

元组

圆括号括起来就是元组,可以简单理解为一个不可变的列表

注意:元组只能保证一级元素不变,但是不能保证二级元素的不可变

元组与列表相同的操作

  • 使用方括号加下标访问元素
  • 切片(形成新元组对象)
  • count()/index()
  • len()/max()/min()/tuple()

元组中不允许的操作,确切的说是元组没有的功能

  • 修改、新增元素
  • 删除某个元素(但可以删除整个元组)
  • 所有会对元组内部元素发生修改动作的方法。例如,元组没有remove,append,pop等方法。

基本操作

1
2
3
4
5
6
7
8
if __name__ == '__main__':
my_tuple = () # 空元组
my_tuple = (1,) # 创建只有一个元素的元组时,得往后面加个逗号
my_tuple = (1, 'a', ['a', 'b'], ('c', 'd', 'e'))
my_tuple[2].append('c') # 如果元组的元素是可变的,那么元组就控制不住了,所以元组的元素尽量用不可变的如数字、字符串和元组
print(my_tuple)
# 运行结果
(1, 'a', ['a', 'b', 'c'], ('c', 'd', 'e'))

字符串

字符串是不可变的序列数据类型

1
2
3
4
if __name__ == '__main__':
my_string = 'hello world!'
print(my_string[1]) # e
my_string[1] = 'a' # 抛异常,因为字符串是不可变的

相关运算

下表实例变量a值为字符串 “Hello”,b变量值为 “Python”:

注意可以用成员运算符,还是挺好使的

+字符串连接(运算速度慢,慎用)a + b‘HelloPython’
*重复输出字符串,相当于乘法a * 2‘HelloHello’
[]通过索引获取字符串中的字符a[1]‘e’
[ : ]截取字符串中的一部分,切片a[1:4]‘ell’
in成员运算符 - 如果字符串中包含给定的字符返回 True“H” in aTrue
not in成员运算符 - 如果字符串中不包含给定的字符返回 True“M” not in aTrue
r/R原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母”r”(可以大小写)以外,与普通字符串有着几乎完全相同的语法。print(r’\n’)\n

多行字符串

用三个双引号或三个单引号,可以跨行编写字符串,其中啥字符也能包含,用来写原生sql,不错

1
2
3
4
5
6
cursor.execute('''
CREATE TABLE users (
login VARCHAR(8),
uid INTEGER,
prid INTEGER)
''')

字符串常用内置操作

字符串内置操作太多了,下面是常用的

  • encode() # 编码成bytes类型

  • find() # 查找子串

  • index() # 获取下标

  • replace() # 替换子串

  • len(string) # 返回字符串长度,Python内置方法,非字符串方法。

  • lower() # 小写字符

  • upper() # 大写字符

  • split() # 分割字符串

  • strip() # 去除两端的指定符号

  • startswith() # 字符串是否以xxx开头

* endswith() # 字符串是否以xxx结尾

字典

Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。

字典包含的元素个数不限,值的类型可以是任何数据类型!但是字典的key必须是不可变的对象,例如整数、字符串、bytes和元组,最常见的还是将字符串作为key。列表、字典、集合等就不可以作为key。同时,同一个字典内的key必须是唯一的,但值则不必。

注意:从Python3.6开始,字典是有序的!它将保持元素插入时的先后顺序!请务必清楚!

字典可精确描述为不定长、可变、散列的集合类型。字典元素在内存中的存储方式是不连续的,也没有链接关系,所以千万不要用列表的序列性质来套字典的性质。

字典的每个键值对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,例如:

1
d = {key1 : value1, key2 : value2 }

基本操作

  • 创建字典

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if __name__ == '__main__':
    my_dict = {} # 创建空字典
    my_dict = {'name': 'sunnyc', 'age': 18} # 直接用key:value形式创建
    print(my_dict)
    my_dict = dict([('name', 'sunnyc'), ('age', 18)]) # 使用内置dict函数创建
    print(my_dict)
    # 运行结果
    {'name': 'sunnyc', 'age': 18}
    {'name': 'sunnyc', 'age': 18}
  • 访问:可以用下标,或get方法

    如果没有键会抛出异常

    1
    2
    3
    4
    if __name__ == '__main__':
    my_dict = {'name': 'sunnyc', 'age': 18} # 直接用key:value形式创建
    print(my_dict['name']) # sunnyc
    print(my_dict.get('age')) # 18
  • 添加和修改

    1
    2
    3
    4
    5
    6
    7
    if __name__ == '__main__':
    my_dict = {'name': 'sunnyc', 'age': 18} # 直接用key:value形式创建
    my_dict['name'] = 'hc' # 修改值,如果key存在的话会把原来的值覆盖
    my_dict['nickname'] = 'sunnyc' # 添加,如果key不存在字典里面的话会添加上这个键值对
    print(my_dict)
    # 运行结果
    {'name': 'hc', 'age': 18, 'nickname': 'sunnyc'}
  • 删除指定键值对,获取键值对的值再删除,清空字典,删除字典

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    if __name__ == '__main__':
    my_dict = {'name': 'sunnyc', 'age': 18, 'nickname': 'su'} # 直接用key:value形式创建
    del my_dict['name'] # 删除指定键值对
    age = my_dict.pop('age') # 获取age的值,然后把这个键值对删了
    print(age)
    print(my_dict)
    my_dict.clear() # 清空字典,成了 {}
    print(my_dict)
    del my_dict # 删除字典,现在这个my_dict连{}都不是了,是 未定义的状态,打印就会抛异常
    print(my_dict)
    # 运行结果
    18
    {'nickname': 'su'}
    {}
    Traceback (most recent call last):
    File "D:/pyproject/python-study/main.py", line 31, in <module>
    print(my_dict)
    NameError: name 'my_dict' is not defined

字典的重要操作

下表是字典的重要操作,其中的getitemskeysvalues是核心中的核心,必须熟练掌握!

方法作用
clear()删除字典内所有元素
copy()返回一个字典的浅复制
fromkeys()创建一个新字典,以序列seq中元素做字典的键
get(key)返回指定键的值,如果键不在字典中,则返回default值
items()以列表返回可遍历的(键, 值) 元组对
keys()以列表返回字典所有的键
values()以列表返回字典所有的值
pop(key)删除并返回指定key的值
popitem()删除并返回字典的最后一个键值对,不接受参数。
setdefault(key, default=None)和get()类似,但如果键不存在于字典中,将会添加键并将值设为default
update(dict2)把字典dict2的键/值对更新到dict里

字典的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if __name__ == '__main__':
my_dict = {'name': 'sunnyc', 'age': 18, 'nickname': 'su'} # 直接用key:value形式创建
# 1. 直接遍历字典取key,根据key取值
for key in my_dict:
print(key, my_dict[key])
# 2. 获取items方法获取键值对,效率低,少用
for key, value in my_dict.items():
print(key, value)
# 3. 利用keys方法获取key
for key in my_dict.keys():
print(key, my_dict[key])
# 4. 利用values方法取值,没办法获取key
for value in my_dict.values():
print(value)

字节

在Python3以后,字符串和bytes类型彻底分开了。字符串是以字符为单位进行处理的,bytes类型是以字节为单位处理的。

bytes数据类型在所有的操作和使用甚至内置方法上和字符串数据类型基本一样,也是不可变的序列对象。

bytes对象只负责以二进制字节序列的形式记录所需记录的对象,至于该对象到底表示什么(比如到底是什么字符)则由相应的编码格式解码所决定。Python3中,bytes通常用于网络数据传输、二进制图片和文件的保存等等。可以通过调用bytes()生成bytes实例,其值形式为 b’xxxxx’,其中 ‘xxxxx’ 为一至多个转义的十六进制字符串(单个 x 的形式为:\x12,其中\x为小写的十六进制转义字符,12为二位十六进制数)组成的序列,每个十六进制数代表一个字节(八位二进制数,取值范围0-255),对于同一个字符串如果采用不同的编码方式生成bytes对象,就会形成不同的值.

相关操作,一般来说最后两个就够用了

1
2
3
4
5
6
7
8
if __name__ == '__main__':
b = b'' # 创建一个空的bytes
b = bytes() # 创建一个空的bytes
b = b'hello' # 指定这个hello是bytes类型
b = bytes('string', encoding='utf-8') # 利用内置的bytes方法创建,字符串转指定编码的bytes
# 以下两种是最省事,最常用的字符串字节转换
string = b'hello'.decode() # 默认utf-8编码解码为字符串
b = string.encode() # 默认utf-8编码转换为bytes

集合(set)

set集合是一个无序不重复元素的集,基本功能包括关系测试和消除重复元素。集合使用大括号({})框定元素,并以逗号进行分隔。但是注意:如果要创建一个空集合,必须用 set() 而不是 {} ,因为后者创建的是一个空字典。集合除了在形式上最外层用的也是花括号外,其它的和字典没有一毛钱关系。

  • 创建和遍历,注意,set集合不能根据下标取值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if __name__ == '__main__':
    empty_set = {} # 空集合不能这样建
    print(type(empty_set)) # <class 'dict'>
    empty_set = set() # 应该这样创建空集合
    print(type(empty_set)) # <class 'set'>
    my_set = {1, 2, 3, 3, 3} # 自动去重
    print(type(my_set))
    print(my_set)
    # 遍历
    for e in my_set:
    print(e)
  • 添加,更新和删除

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if __name__ == '__main__':
    my_set = {1, 2, 3, 3, 3} # 自动去重
    my_list = [3, 3, 2, 6, 6, 8, 8]
    my_set.update(my_list) # update方法接收一个序列,会把序列中的元素去重然后放set里面
    my_set.update("hello") # 也会把hello去重放进去 {1, 2, 3, 6, 8, 'o', 'l', 'e', 'h'}
    my_set.add(6) # 添加新元素
    my_set.remove('h') # 会删除指定的元素
    print(my_set)
    # 运行结果
    {1, 2, 3, 'e', 6, 8, 'l', 'o'}

流程控制

顺序执行

Python代码在执行过程中,遵循下面的基本原则:

  • 普通语句,直接执行;
  • 碰到函数,将函数体载入内存,并不直接执行
  • 碰到类,执行类内部的普通语句,但是类的方法只载入,不执行
  • 碰到if、for等控制语句,按相应控制流程执行
  • 碰到@,break,continue等,按规定语法执行
  • 碰到函数、方法调用等,转而执行函数内部代码,执行完毕继续执行原有顺序代码

关于程序的入口

import文件内的if name = main不会执行,主程序内的代码if name = main会执行

知乎这个讲的不错:https://www.zhihu.com/question/49136398

条件判断

  • 在Python中没有switch – case语句
  • 下面是条件判断的使用方法
1
2
3
4
5
6
7
8
9
if __name__ == '__main__':
a = 10
b = 5
if a > b:
print("a > b")
elif a < b:
print("a < b")
else:
print("a = b")

循环

while

python中没有do while,但是while还有一个else从句

1
2
3
4
5
6
7
8
if __name__ == '__main__':
a = 1
while a < 10:
a += 1
if a == 6:
break # 程序执行中被打断,不会走else分支
else:
print("执行完毕")

for

使用方法

1
2
for <variable> in <sequence>:
<statements>

for也有else从句,用法和while的那个一样