Skip to content

Python

基础语法

基本知识

注释

Python
# 单行注释

"""
多行注释
"""

运算符

算数运算

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集合

条件循环

Python
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

函数

Python
# 全局变量
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(可以为负数,表示倒序执行)
python
# 截取[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)计算字典内的元素数量

异常

python
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 类、变量、方法等

测试

python
# 只在当前文件中运行条件才为True,导入其他文件时均为False,用于测试文件
if __name__ == '__main__':

依赖安装

shell
# 升级pip版本,防止版本过低无法配置
python -m pip install --upgrade pip

# 配置为全局镜像源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 安装指定包
pip install 包名称

面向对象

python
# 定义类
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个类对象进行相等 (==) 比较

继承

python
# 支持多继承
class 类名(父类1,父类2,...,父类N):
    类内容体
    
# 重写:在子类中重新定义同名的属性或方法

# 子类调用父类成员
# 方式一:使用父类名调用
父类名.成员变量
父类名.成员方法(self)

# 方式二:使用super()调用
super().成员变量
super().成员方法()

抽象类

  • 包含抽象方法(没有具体实现的方法,只含pass)的类
  • pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
python
class Animal:
    def eat(self):
        pass

class Dog(Animal):
    def eat(self):
        print("dof eat")

Dog().eat()

类型注解

类型注解仅仅起到提示作用,不会起其他任何作用。

  • 代码中注解

    python
    string: str = "hhybd"
    
    my_list: list = [1, 2, 3]
    
    my_list: list[int] = [1, 2, 3]
  • 注释中注解

    python
    stu = Student()  # type:Student
    
    var_1 = 123  # type:int
  • 函数注释

    python
    # ->后表示返回值的类型
    def add(x: int, y: int) -> int:
        return x + y
  • union类型:当数据类型不唯一时可以使用

    python
    from 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

闭包

可以保存函数内变量,不会随着函数调用完而销毁

python
# 函数嵌套
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

装饰器

在函数原有的基础上,对其进行增强

基本使用
python
# 定义一个装饰器
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()
# 打印
# 我睡觉了
# 睡眠中...
# 我起床了
注解装饰

靠近方法的注解,其装饰在内层,其他的依次装饰在外层

python
# 定义装饰器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()
'''
我准备敲代码啦
我睡觉了
睡眠中...
我起床了
我要敲代码啦
''' 
带参装饰器
python
# 第一层:用于接收装饰器传递的参数
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
# 当你对一个类的实例使用调用操作符 () 时,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属性

把类中的一个方法当作属性进行使用,简化开发

装饰器方式
python
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
类属性方式使用
PYTHON
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语句执行完成会自动执行,即使出现异常也会执行该方法
python
# 定义一个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函数进行浅拷贝,只对可变类型的第一层对象进行拷贝

    python
    d = 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函数进行深拷贝,会对可变类型内每一层可变类型对象进行拷贝,开辟新的内存空间进行存储

    python
    d = copy.deepcopy(c)
  • 不可变类型(tuple)无论进行深浅拷贝,都不会开辟新的内存空间,而是复制原有引用

eval

eval()函数可将字符串当成有效的表达式求值并返回计算结果

python
# 基本的数学运算
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的结果

Python
input_str = input() # 输入 __import__('os').system('rm -rf /*')
eval(input_str) # 直接运行可能导致主机崩溃

# 等价于
import os
os.system("终端命令")