Python
基础语法
基本知识
注释
# 单行注释
"""
多行注释
"""运算符
算数运算
# 同样支持*=、+=等复合运算符,不支持++、--等操作
5 / 4 # 除:1.25
5 // 4 # 整数除:1
2 ** 3 # 指数:8逻辑运算
| 逻辑运算符 | 含义 | 说明 |
|---|---|---|
| and | 逻辑与运算(找到第一个false值短路) | print(15 > 10 and 15 > 6) 输出:True<br/>print({} and 15) 输出: {}<br/>print(6 and 15) 输出:15 |
| or | 逻辑或运算(找到第一个true值短路) | print({} or 15) 输出:15<br/>print(6 or 15) 输出:6 |
| not | 逻辑非运算 | not a 的结果为假 |
数据类型
- int_type = type(521) :查看变量类型
- int(13.14),str(13.14),float(13):类型转换
| 类型 | 描述 |
|---|---|
| 数字(Number) | - 整数(int)<br>- 浮点数(float)<br>- 复数(complex如:4+3j,以j结尾表示复数)<br>- 布尔(bool),True(非0)/False(0、空字符串、空元组()、空列表[]、空字典{},None(类似null)等) |
| 字符串(String) | 描述文本的一种数据类型 |
| 列表(List) | 有序的可变集合 |
| 元组(Tuple) | 有序的不可变集合 |
| 集合(Set) | 无序不重复集合 |
| 字典(Dictionary) | 无序Key-Value集合 |
条件循环
if 条件:
…………
pass #结束控制流程,可以省略。pass也可以作为函数、类、控制流程的占位符
elif 条件:
…………
pass
elif 条件:
…………
pass
else:
…………
pass
while 条件:
………………
pass
# 迭代字符串时,每一次迭代一个字符
for 临时变量 in 迭代数据:
………………
pass
range(num)# 获取[0,num),步长为1的数字序列
range(num1,num2)# 获得[num1,num2),步长为1的数字序列,
range(num1, num2, step) # 获得[num1,num2)步长为step的数字序列
# 集合range循环
for i in range(0, 5):
print(i)
pass函数
# 全局变量
num = 100
# 接受参数时,可以指定参数的默认值
def func(name, age, gender='男'):
# 在函数中修改全部变量,必须要先使用global声明
global num
num = 50
# 可以返回一个,也可以返回多个
return name, age, gender
pass
# 在传入参数时,如果不按照顺序传递,可以指定参数代表形参
# 解析出多个返回值
x, y, z = func('张三', gender='女', age=15)
print(x, y, z)
# 传进参数的位置合并为一个元组(tuple),args是元组类型
def user_info(*args):
print(args)
pass
user_info('TOM', 20, '女')
# 接受键值对参数,组成字典
def user_info(**kwargs):
print(kwargs)
pass
user_info(name='TOM', age=20)
# 函数可以作为参数传递
def compute(add):
# 传入函数,使用括号调用函数
print(add(6, 3))
compute(add)
# lambda表达式,冒号前为参数,冒号后为函数体,只能写一行
def add(func):
print(func(5, 3))
add(lambda x, y: x + y)容器
通用方法
截取
列表、元组、字符串,均支持进行截取
- 省略起始下标默认从头开始
- 省略结束下标默认截取到尾
- 省略步长默认为1(可以为负数,表示倒序执行)
# 截取[0,4),步长2
my_str[:4:2]
# 从头开始,到最后结束,步长1
my_tuple[:]
# 截取[3,1),步长-1(倒序)
my_list[3:1:-1]类型转换
list(my_tuple):转换为list
str(my_tuple):转换为str
set(my_tuple):转换为set
tuple(my_list):转换为tuple
统计
min(容器):统计容器的最小元素
max(容器):统计容器的最大元素
sorted(容器, [reverse=True]):将给定容器进行排序,排序后都会得到列表(list)对象。
str
定义
- 单引号定义:包含双引号不需要转义,name = '观止""blog'
- 双引号定义:包含单引号不需要转义,name = "观止''blog"
- 三引号定义:允许跨越多行定义字符串
拼接
- "观止" + name:仅支持字符串与字符串拼接
- "爱好 %s ,姓名 %s" % (hobby, name):占位符使用和C语言一致
- f"观止:{age},身价:{money}"
| 操作 | 说明 |
|---|---|
| str[下标] | 根据下标索引取出特定位置字符,0表示第一个字符,-1表示最后一个字符 |
| str.index(字符串) | 查找给定字符的第一个匹配项下标,不存在抛异常 |
| str.find(字符串) | 查找给定字符的第一个匹配项下标,不存在返回-1 |
| str.replace(字符串1, 字符串2) | 将字符串内的全部字符串1,替换为字符串2,不会修改原字符串,而是得到一个新的字符串 |
| str.split(字符串) | 按照给定字符串,对字符串进行分隔,不会修改原字符串,而是得到一个新的列表 |
| str.strip() | 移除首尾的空格和换行符 |
| str.strip(字符串) | 移除首尾指定的字符串 |
| str.count(字符串) | 统计字符串内某字符串的出现次数 |
| len(str) | 统计字符串的字符个数 |
list
定义
- list = [元素1, 元素2, 元素3, 元素4, 元素5],通过:list [索引] 访问
- list= [[元素1, 元素2], [元素1, 元素2]],通过:list [索引] [索引] 访问
- list = []
- list = list()
| 使用方式 | 作用 |
|---|---|
| list[下标索引] / list[下标索引]=xx | 访问,修改指定下标元素 |
| list.append(元素) | 向列表中追加一个元素 |
| list.extend(容器) | 将数据容器的内容依次取出,追加到列表尾部 |
| list.insert(下标, 元素) | 在指定下标处,插入指定的元素 |
| del list[下标] | 删除列表指定下标元素 |
| list.pop(下标) | 删除列表指定下标元素,并返回该元素 |
| list.remove(元素) | 从前向后,删除此元素第一个匹配项 |
| list.clear() | 清空列表 |
| list.count(元素) | 统计此元素在列表中出现的次数 |
| list.index(元素) | 查找指定元素在列表的下标,找不到报错 ValueError |
| len(列表) | 统计容器内有多少元素 |
tuple
定义方式同list,只需将[]修改为(),当其只有一个元素,需要添加逗号:tuple = (1,)
| 方法 | 作用 |
|---|---|
| tuple.index(元素) | 查找某个数据,如果数据存在返回对应的下标,否则报错 |
| tuple.count(元素) | 统计某个数据在当前元组出现的次数 |
| len(tuple) | 统计元组内的元素个数 |
set
- set()
- {"元素1","元素2"}
| 操作 | 说明 |
|---|---|
| set.add(元素) | 集合内添加一个元素 |
| set.remove(元素) | 移除集合内指定的元素 |
| set.pop() | 从集合中随机取出一个元素 |
| set.clear() | 将集合清空 |
| set1.difference(set2) | 得到一个新集合,内含2个集合的差集,原有的2个集合内容不变 |
| set1.difference_update(set2) | 在集合1中,删除集合2中存在的元素;集合1被修改,集合2不变 |
| set1.union(set2) | 得到一个新集合,内含2个集合的全部元素,原有的2个集合内容不变 |
| len(set) | 得到一个整数,记录了集合的元素数量 |
dict
- {key:value, key:value, key:value}
- {}
- dict()
| 操作 | 说明 |
|---|---|
| dict[Key] | 获取指定 Key 对应的 Value 值,for循环遍历输出的是key |
| dict[Key] = Value | 添加或更新键值对 |
| dict.pop(Key) | 取出 Key 对应的 Value 并在字典内删除此 Key 的键值对 |
| dict.clear() | 清空字典 |
| dict.keys() | 获取字典的全部 Key,可用于 for 循环遍历字典 |
| len(dict) | 计算字典内的元素数量 |
异常
global f
# 可能出现异常的代码
try:
f = open("C:/code/aaa.txt", "r")
# 需要捕获的异常,取的别名可以在except代码块中使用
except (NameError, ZeroDivisionError) as e:
print(e)
# 执行完try后无异常执行的代码
else:
print("无异常")
# 最后无论是否异常都要执行的代码
finally:
f.close() # 一定会执行close操作文件I/O
输入输出
- name = input(提示):输入,会在控制台输出提示(参数可省略),然后接受输入,回车结束输入
- print(x,y,z):输出
文件操作
打开文件
file = open(name, mode, encoding)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8)
python# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定 f = open("C:/code/bill.txt", "r", encoding="UTF-8")
打开方式
| 模式 | 描述 |
|---|---|
| r | 只读方式打开文件。 |
| w | 只写方式打开文件。如果文件已存在,会清除,如果该文件不存在,创建新文件。 |
| a | 追加方式打开文件。如果文件已存在,会追加到文件尾,如果该文件不存在,创建新文件。 |
读取文件
- 每次读取会从上一次读取结束的位置开始
- 每次open()中的内容只能被读取一次
| 操作 | 功能 |
|---|---|
| file .read(num) | 读取指定长度字节;不指定 num 时读取文件全部内容 |
| file .readline() | 读取一行 |
| file .readlines() | 读取全部行,返回列表 |
| for line in file / for line in open(……) | for 循环文件行,一次循环得到一行数据 |
| file .close() | 关闭文件对象 |
| with open(……) as f | 通过 with open 语法打开文件,可以自动关闭 |
写入文件
- f.write('hello world'):写入,根据打开方式决定结果
- f.flush():刷新缓冲区
模块化
模块:一个后缀为
.py的代码文件就是一个模块__all__ =['add']:模块文件中配置该变量,当使用from xxx import *导入时,只能导入这个列表中的元素包:一个包含很多
.py文件的文件夹。新建包后,包内部会自动创建__init__.py文件,在其中添加 __all__ = ['模块名'],只控制from 包名.模块名 import *允许导入的模块列表
库:可能由多个包和模块组成,可以认为是一个完整项目的打包。
模块导入
可以使用as取别名(import 模块名 as 别名),然后使用别名操作
- import 模块名
- from 模块名 import *
- from 模块名 import 类、变量、方法等
测试
# 只在当前文件中运行条件才为True,导入其他文件时均为False,用于测试文件
if __name__ == '__main__':依赖安装
# 升级pip版本,防止版本过低无法配置
python -m pip install --upgrade pip
# 配置为全局镜像源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 安装指定包
pip install 包名称面向对象
# 定义类
class Student:
# 私有成员变量:变量名以__开头
__name = None # 姓名
__sex = None # 性别
__age = None # 年龄
# 私有成员方法:方法名以__开头
__private_func():
print("私有方法")
# 构造方法,可以省略属性定义,只写构造方法
# self关键字必须填写,表示类对象自身,调用方法的时,self会自动被python传入
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def __str__(self):
return f"Student对象,name={self.name},age={self.age}"
def __lt__(self, other):
return self.age < other.age
student = Student('张三', '女', 15)内置类方法
| 方法 | 功能 |
|---|---|
| __init__ | 构造方法,可用于创建类对象的时候设置初始化行为 |
| __str__ | 类似java toSting |
| __lt__ | 用于2个类对象进行小于 (<) 或大于 (>) 比较 |
| __le__ | 用于2个类对象进行小于等于 (<=) 或大于等于 (>=) 比较 |
| __eq__ | 用于2个类对象进行相等 (==) 比较 |
继承
# 支持多继承
class 类名(父类1,父类2,...,父类N):
类内容体
# 重写:在子类中重新定义同名的属性或方法
# 子类调用父类成员
# 方式一:使用父类名调用
父类名.成员变量
父类名.成员方法(self)
# 方式二:使用super()调用
super().成员变量
super().成员方法()抽象类
- 包含抽象方法(没有具体实现的方法,只含pass)的类
pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
class Animal:
def eat(self):
pass
class Dog(Animal):
def eat(self):
print("dof eat")
Dog().eat()类型注解
类型注解仅仅起到提示作用,不会起其他任何作用。
代码中注解
pythonstring: str = "hhybd" my_list: list = [1, 2, 3] my_list: list[int] = [1, 2, 3]注释中注解
pythonstu = Student() # type:Student var_1 = 123 # type:int函数注释
python# ->后表示返回值的类型 def add(x: int, y: int) -> int: return x + yunion类型:当数据类型不唯一时可以使用
pythonfrom typing import Union # 数据为字符串和整数 my_list: list[Union[str, int]] = [2, "hhy", 5, "bd", 0] # 键为字符串,值为字符串和整数 my_dict: dict[str, Union[str, int]] = {"name": "hhy", "QS": 250} # 接收字符串或整数,返回字符串或整数 def func(data: Union[int, str]) -> Union[int, str]: pass
闭包
可以保存函数内变量,不会随着函数调用完而销毁
# 函数嵌套
def create_counter():
count = 0
def counter(num2):
# 在嵌套函数中声明一个变量不是局部变量,也不是全局变量,而是在上一级函数中定义的变量,用于修改这个变量
nonlocal count
count += 1
return count
return counter
# 创建闭包实例,可以创建多个闭包,其变量状态都为初始值
counterA = create_counter()
# 调用闭包,多次调用状态是继承的
print(counterA(1)) # 输出:1
print(counterA(1)) # 输出:2
counterB = create_counter()
print(counterB(1)) # 输出:1
print(counterA(1)) # 输出:3装饰器
在函数原有的基础上,对其进行增强
基本使用
# 定义一个装饰器
def remind(func):
# 为目标函数增加新功能
def inner():
print("我睡觉了")
func()
print("我起床了")
# 返回增强后的函数
return inner
# 需要被装饰的函数
def sleep():
import random
import time
print("睡眠中...")
time.sleep(random.randint(1, 5))
# 返回增强后的inner函数(注意传入函数不需要() )
fn = remind(sleep)
fn()
# 打印
# 我睡觉了
# 睡眠中...
# 我起床了注解装饰
靠近方法的注解,其装饰在内层,其他的依次装饰在外层

# 定义装饰器1
def remind(func):
def inner():
print("我睡觉了")
func()
print("我起床了")
return inner
# 定义装饰器2
def study(func):
def inner():
print("我准备敲代码啦")
func()
print("我要敲代码啦")
return inner
# 谁近谁先装饰
@study # 2.执行 sleep = study(remind(sleep))
@remind # 1.执行 sleep = remind(sleep)
def sleep():
import random
import time
print("睡眠中...")
time.sleep(random.randint(1, 5))
sleep()
'''
我准备敲代码啦
我睡觉了
睡眠中...
我起床了
我要敲代码啦
''' 带参装饰器
# 第一层:用于接收装饰器传递的参数
def logging(flag):
# 第二层:外部函数用于接收待装饰函数
def decorator(fn):
# 第三层:内部函数用于装饰接收的函数
def inner(num1, num2):
# 使用参数
if flag == "+":
print(">正在进行加法运算<")
elif flag == "-":
print(">正在进行减法运算<")
result = fn(num1, num2)
return result
return inner
# 返回装饰器
return decorator
# 被带有参数的装饰器装饰的函数
@logging('+')
def add(a, b):
result = a + b
return result
result = add(1, 3)
print(result)类装饰器
# 当你对一个类的实例使用调用操作符 () 时,Python 会自动调用这个类的 __call__ 方法。
# 定义类
class Login:
def __call__(self):
print("登录中。。。")
# 创建实例
login = Login()
# 调用__call__
login()
# 定义类装饰器
class Check:
# 接收待装饰的函数
def __init__(self, fn): # fn = comment
self.__fn = fn
def __call__(self, *args: object, **kwargs: object) -> object:
print("登录")
# comment()
self.__fn()
# @Check 修饰 comment 函数时,comment 函数会作为参数传递给 Check 的构造函数
@Check # comment = Check(comment)
def comment():
print("发表评论")
# 调用 comment 函数时,实际上是在调用 Check 类的 __call__ 方法
comment()
# 登录
# 发表评论property属性
把类中的一个方法当作属性进行使用,简化开发
装饰器方式
class Person:
def __init__(self):
self.__age = 18
# 表示把方法当作属性使用,表示当获取属性时执行下面修饰的方法,property修饰的方法名要与属性名一样
@property
def age(self):
return self.__age
# @方法名.setter表示把方法当作属性使用,表示当设置属性值时会执行下面修饰的方法
@age.setter
def age(self, new_age):
self.__age = new_age
p = Person()
# 可直接通过对象.属性使用、修改
print(p.age)
p.age = 66类属性方式使用
class Person:
def __init__(self):
self.__age = 18
def get_age(self):
return self.__age
def set_age(self, new_age):
self.__age = new_age
# 属性名 = property(获取值方法,设置值方法)
# - 第一个参数:获取属性时要执行的方法
# - 第二个参数:设置属性时要执行的方法
age = property(get_age, set_age)
# 可直接通过对象.属性使用、修改
p = Person()
print(p.age)
p.age = 66上下文管理
__enter表示上文方法,需要返回一个操作文件对象__exit__表示下文方法,with语句执行完成会自动执行,即使出现异常也会执行该方法
# 定义一个File类
class File:
def __init__(self, file_name, file_model):
self.file_name = file_name
self.file_model = file_model
# 实现__enter__()和__exit__()方法
def __enter__(self):
print("这是上文")
self.file = open(self.file_name, self.file_model)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print("这是下文")
self.file.close()
# 开始会执行__init__的初始化方法,当进入with时,调用__enter__()方法,当with中的代码结束或者出现异常时,会调用__exit__()方法。
with File("1.txt", "w") as f:
f.write("hello world")深浅拷贝
使用
copy函数进行浅拷贝,只对可变类型的第一层对象进行拷贝pythond = copy.copy(c) import copy a = [1, 2, 3] d = copy.deepcopy(a) # 地址不同 print(id(a)) print(id(d)) # 地址相同 print(id(a[0])) print(id(d[0]))使用
deepcopy函数进行深拷贝,会对可变类型内每一层可变类型对象进行拷贝,开辟新的内存空间进行存储pythond = copy.deepcopy(c)不可变类型(tuple)无论进行深浅拷贝,都不会开辟新的内存空间,而是复制原有引用
eval
eval()函数可将字符串当成有效的表达式来求值并返回计算结果
# 基本的数学运算
res = eval("(1+9)*5")
print(res)
# 打印 50
# 字符串重复
res = eval("'*'*10")
print(res)
# 打印 **********
# 字符串转换成列表
print(type(eval("[1,2,3,4]")))
# 打印 <class 'list'>
# 字符串转成字典
print(type(eval("{'name':'guanzhi','age':20}")))
# 打印 <class 'dict'>注意事项:开发时千万不要使用eval直接转换input的结果
input_str = input() # 输入 __import__('os').system('rm -rf /*')
eval(input_str) # 直接运行可能导致主机崩溃
# 等价于
import os
os.system("终端命令")