Python基础-----笔记 前言Python这门以简洁、易读著称的解释型编程语言已经成为全球最受欢迎的编程工具之一。无论你是刚踏入编程世界的新手还是希望快速开发应用的工程师Python 都能以其丰富的库生态和清晰的语法帮助你实现想法我看的教学视频是尚硅谷的 写这篇文章的目的就是巩固自己所学一、Python 安装与环境配置开始写代码之前我们需要下载Python解释器 确保有相关的环境 这里以windows下载为例 其它的系统如Linux,mac一样的逻辑1. 下载 Python打开官方网站Python 官网https://www.python.org/点击导航栏的Downloads根据你的操作系统选择对应版本下载建议选择最新的稳定版本如 Python 3.x箭头所指的版本应该就是目前最新最稳定的版本了点击Windows进来之后 左侧的这一列都是稳定的版本号了 我们下载这一列的就行Explain: 看你系统是多少位的下载对应的即可 查看方式如下如果你是ARM的处理器 也是要下载对应的即可3.下载完成后运行安装程序⚠️安装小提示勾选Add Python to PATH这样可以在命令行直接使用python命令。默认选项通常已经适合大部分用户无需修改其他设置。建议将这个目录改成了2. 验证安装是否成功安装完成后打开命令行Windows 下是 CMD(快捷方式WinR)或 PowerShellmacOS/Linux 下是 Terminal输入:python --version如果出现类似Python 3.x.x的版本信息就表示安装成功了 我的版本比较老了3.11.9插一嘴 这个cmd的样式可以DIY 这里我提供一下方法如果大家想设置的话Cmd样式设置鼠标放到上面的白色选项栏中鼠标右击 然后点击设置之后来到这个界面 左侧往下滑 点击命令提示符这里可以设置背景图片的路径 以及透明度 我个人觉得百分之50就挺好二、Python 第一个程序安装完成后我们可以尝试编写人生中的第一个 Python 程序Hello, World!打开刚刚的cmd窗口输入python输入以下代码print(Hello, World!)回车恭喜你你已经成功编写并运行了第一个 Python 程序三、下载编辑器我们需要一个方便 高效率的集成代码环境(IDE) 常见的有 Pycharm Vscode通常有以下的功能:代码编辑器可以自定义代码编辑器自动补全/语法高亮:提升编程体验项目管理工具组织文件管理工程结构调试器更快的找出代码中的错误打开jetbrains的官网 直接点击下面的连接即可https://www.jetbrains.com/pycharm/download/?sectionwindowshttps://www.jetbrains.com/pycharm/download/?sectionwindows现在的不叫专业版了 叫完整版 和社区版 区别就是 之前你如果下了专业版 到了30天试用之后 连Pycharm都打不开 现在就不会有这个问题 直接下载这个即可(电脑是ARM架构的选下面那个)当然也可以试用工具破解 这里就不演示了 大家可以去网上搜 或者私信我 我也可以帮助你学习前期是不需要使用到付费功能的按照提示安装即可 和解释器一样 修改安装目录(目标目录最好是英文) 看个人习惯一.字面量知识总结字面量就是直接写在代码里面中的具体值Python的字符串中可以包含任意字符 且必须使用引号包起来字符串的引号 可以是单引号 双引号 三个单引号写在Python文件头部的字符串会被自动识别成docstring(文档字符串)文档字符串的主要作用是对当前Python文件进行一些说明 且文档字符串必须使用三个双引号调整了Pycharm的设置检查代码 Ai智能提示二.标识符的命名规则只能包含:数字字母下划线且不能以数字开头 不能包含空格标识符区分大小写 例如:Name和name是两个不同的标识符标识符不能使用关键字 例如:class pass标识符尽量不要与内置函数同名标识符虽然没有长度限制,但应追求:简洁清晰具有描述性Python官方建议采用蛇形命名法(user_name) 除此之外还有小驼峰(userName) 大驼峰(UserName)命名法三.常量常量就是一旦被赋值就不希望改变的量(区别于变量)Python中一般约定使用全大写变量名来表示常量涉及到多个单词时用下划线做分割Python中没有强制的常量机制Python中所谓的常量其本质其实还是变量只不过我们约定好不去修改不像别的强语言类型(比如Java c)四.注释注释就是对代码的备注和解释在代码执行时通常不起任何作用注释分为三类单行注释# 后的一行内容会被视为注释;多行注释使用三个单引号或三个双引号的方式编写(Python中其实没有真正的多行注释语法上述方式编写的多行注释 本质是 一个字符串的字面量)文件编码注释:写在Python文件开头用于指定当前文件的字符编码(Python3默认使用的是Utf-8编码(也叫万国码) 所以不需要再每个py文件开头写#codingutf-8)数据类型:在Python中变量没有类型数据有类型整型就是没有小数点的数字可以是正数 负数 也可以是0当数很大时我们可以使用下划线将数字进行分组让数字变得更易读(例如:2_000_000)Python中整数的上限值取决于执行代码的计算机的内存和处理能力浮点型就是带有小数点的数字浮点型的科学计数法表示: 3.14e3/3.14E3(3.14*10的3次方) 3.14e9/3.14E9(3.14*10的9次方)3.14e-2/3.14E-2(3.14*10的-2次方)五.字符串单引号和双引号的写法是等价的,二者都不能直接换行(要用圆括号才能换行)三个单引号的写法可以直接换行并且可以作为多行注释使用 三个双引号还可以作为文档字符串使用格式化输出: 号拼接 %s占位符 f-string(Python最推荐的形式)Unicode编码 查看字符对应的编码ord() 将字符转换成编码chr() 字符串比较的是Unicode编码布尔类型是Int类型的子类型 底层的本质是用1表示True 用0表示FalseAnd返回的值不一定是布尔值 它返回的是某个参与计算的值本身and 会先看左边 如果左边是假 就直接返回左边否则返回右边 若参与and运算的值不是布尔值 那python会自动转换为布尔值然后再进行逻辑操作Or 会先看左边 如果左边为真 就直接返回左边 否则返回右边Not取反 返回的值 一定是布尔值六.循环主要区别就是是否知道循环的次数七.函数关键字参数使用函数时通过形参名值的形式传递实参注意使用关键字参数时位置参数必须在关键字参数之前函数限制传参的方式具体规则/ 前面只能用位置参数* 后面只能用关键字参数 两个同时使用时, / 必须在 * 前面函数参数的默认值参数默认值:定义函数时通过形参名值的形式为参数指定一个默认值默认参数必须放在必选参数的后面或者说某个形参一旦设置了默认值拿它后面的所有形参也必须要写默认值For example: Print函数底层 设置了end默认值\n函数可变参数1.可变位置参数 定义函数时在形参的名前加 * ,可以接收任意数量的位置参数并打包成一个元组2.可变关键字参数定义函数时在形参的名前加 ** ,可以接收任意数量的关键字参数并打包成一个字典如果要一起使用的话 可变位置参数得在可变关键字参数之前特殊的字面量---NoneNone是一个特殊的字面量它表示空值/无意义/无值None的类型是NoneType.None转换为布尔值是False.None不能参与数学运算也不能与字符串拼接不给函数设置返回值函数会默认返回None.局部作用域和局部变量会在函数调用时创建在函数执行后销毁全局作用域和全局变量会在程序开始时创建在程序结束后销毁函数递归调用 指的是自己调用自己的一种操作数据容器数据容器 一种能存放多个数据的数据类型数据容器可以更高效地管理成批的数据且便于存储访问容器中的每一个数据 称为每一个元素Python中有很多种数据容器不同的数据容器有不同的特点不同的语法共性就是可以存储多个元素列表集合面向对象基础什么是面向对象? 编程思想,封装(就是将某些功能聚合起来 方便后续的调用 比如函数)继承(子承父业 子类继承父类的属性和方法)多态(同一个事物有着不同的形态)面向对象的基本概念 类和对象概念类和对象编程语法self使用添加和获取对象属性 属性概念类外部类内部获取属性魔法方法概念,__init__,__str__,__del__面向对象和面向过程编程思想就是人们利用计算机来解决问题的思维分类面向过程它是一种编程思想强调的是以步骤(过程)为基础完成各种操作面向对象它是一种思想强调的是以对象为基础完成各种操作它是基于面向过程的说到面向对象 不得不提的就是它的三大思想特点 :更符合人们的思考习惯把复杂的事情简单化把人们(程序员)从执行者变成指挥者举例: 越符合当时的场景越好例如:买电脑洗衣服总结万物皆对象面向对象的三大属性封装封装就是隐藏对象的属性和实现细节仅对外公开接口控制在程序中属性的读和修改的访问级别将抽象得到的数据和行为相结合形成一个有机的整体也就是将数据与操作数据的源代码进行有机的结合形成类,其中数据和函数都是类的成员封装的目的是简化编程增强安全性 使用者不必了解具体的实现细节而只是要通过外部接口以特定的访问权限来使用类的成员多态 同一个函数接收不同的对象 有不同的效果Self关键字在类外访问类的行为(函数) 需要通过对象名.的方式进行访问在类内访问类的行为 需要通过 self.进行访问Python 在类外可以给对象设置属性 对象.属性名...Python中类内访问成员 可以通过self. 的方式魔法方法特点:Python内置的函数 在特定的场景下会被自动调用常用的魔法方法__init__在(每次)创建对象的时候会自动触发该类的__init__() 函数__str__当使用print()函数时 会自动调用该对象所在类的str魔法方法 该魔法方法默认打印的是对象的地址值 无意义 一般会重写 改为打印 对象的各个属性__del__当.py文件执行结束 或者手动del释放对象资源会自动调用该函数定义类的三种语法class 类名: / class 类名(): / class 类名(object):object是所有类的父类继承的优点提高代码的复用性弊端:耦合性变强了父类不好的内容 子类想没有都不行开发规则高内聚(指的是类自己独立处理问题的能力) 低耦合(指的是类与类之间的关系)MRO机制Python中有MRO机制可以查看某个对象在调用函数时的顺序类名.mro() or 类名.__mro__多继承时不同类中有相同的属性和方法时 按照从左往右就近原则继承子类重写父类同名方法和属性重写也叫作覆盖就是当子类属性或方法与父类的属性或方法名字相同时从父类继承下来的成员可以重新定义子类重写父类的属性和方法优先会调用子类的属性和方法子类访问父类成员method_1父类名.父类函数名(self) ---- 精准访问method_2super().父类函数名(self) ---- 只能访问最近的那个类有就用 没有就报错(旧版本) 继续找下一个(新版) 推荐单继承使用私有属性和私有方法:在 Python 中可以为属性和方法设置私有权限即设置某个属性或方法不继承给子类。设置私有属性和方法的方式在属性或方法名前面加上__双下划线格式好处:提高了代码的安全性 以及复用性坏处:代码量增加了多态入门要有继承要有方法的重写 不然多态毫无意义要有父类引用子类对象抽象类解释:在Python中 抽象类接口 有抽象方法的类就是 抽象类 也叫接口抽象方法 没有方法体的方法, 即方法体是pass修饰的作用: 抽象类一般充当父类用于指定行业规范准则 具体的交由子类来完成对象属性和类属性:它是一个名字 用来描述事物的外在特征的.对象属性属于每个对象的即: 每个对象的属性值可能不同 修改A对象的属性 不影响对象B定义到__init__魔法方法中的属性 只能通过对象名.的方式调用类属性: 属于类的即: 能被该类下所有的对象所共享. 要想改变类属性的值 必须通过 类名.的形式类方法和静态方法类方法 属于类的方法可以通过类名. 还可以通过 对象名. 的方式来调用定义类方法的时候必须使用装饰器classmethod 且第一个参数必须表示 类对象.静态方法属于类下所有对象所共享的方法可以通过类名. 还可以通过 对象名. 的方式类调用定义静态方法的时候必须使用装饰器staticmethod且参数可传 可不传区别 如果函数中要用 类对象 就定义成类方法 反之即可闭包装饰器与深浅拷贝闭包就是 函数嵌套时内层函数调用了外部函数的变量且外层函数把内参函数返回形成的带记忆功能的函数nonlocal是Python内置的关键字可以实现在内部函数中 修改外部函数的变量值闭包的条件: 有嵌套 有引用 有返回闭包的核心作用:延长变量生命周期封装数据实现私有变量效果实现轻量级的状态保持装饰器的作用不改变原有函数的基础上给原有函数增加额外功能 其本质就是一个闭包函数写法1. 传统写法 装饰后的函数名 装饰器名(被装饰的原函数) 装饰后的函数名()2. 语法糖(最常见也最实用). 在要被装饰的原函数上。直接写装饰器名之后直接调用原函数即可装饰器的内部函数格式 要和被装饰器的原函数保持一致多个装饰器装饰一个原函数 是按照 由内向外的顺序来装饰的 用装饰器来做的话 看到的效果是从上到下执行的装饰器的参数只能有一个 要传入多个参数的话 在该装饰器的外边再包裹一层把该装饰器当作其内部函数返回即可深浅拷贝:浅拷贝就是copy模块的copy()函数 深拷贝就是copy模块中的deepcopy()深拷贝主要是针对可变参数类型来讲的深拷贝拷贝所有层 浅拷贝只拷贝第一层网络编程介绍概述就是用来实现网络互联的 不同计算机上运行的程序间 可以进行数据交互三要素IP地址设备(电脑 手机 Ipad)在网络中唯一的标识分类:IPV4, 4字节 十进制 例如192.168.88.100IPV6 16字节 十六进制 宣传语: 可以让地球上的每一粒沙子都有自己的IP两个DOS命令查看IP:windows: ipconfigLinux: ifconfig测试网络连接:ping ip地址 或 域名端口号程序在设备上的唯一标识范围 0-65535,其中0-1023已经被系统占用或者用作保留端口,自定义端口时尽量规避这个范围协议: 传输规范 规则常用的协议:TCP(常用) UDPTCP特点:1.面向有线连接2.采用字节流传输数据 理论无大小限制3.安全(可靠)协议4.效率相对较低5.区分客户端和服务端网络编程介绍概述: 网络编程也叫网络通信 Socket通信即:通信双方都独有自己的Socket对象 数据在Socket之间通过数据报包(UDP协议) 或者字节流(TCP协议)的形式进行传输For example:你和你遥远的朋友在聊天 表面是你们两个人在交互 其实是通过 两部手机(双方各自的手机)来交互的代码写法(入门创建Socket对象)# 导包 import socket ​ # 创建Socket对象 # 参1: Address Family, 地址族, 即: Ipv4 还是 IpV6, 默认值: AF_INET(ipv4) AF_INET6(ipv6) # 参2: Socket Type, Socket类型, 即: TCP 还是 UDP, 默认值: SOCK_STREAM(TCP) SOCK_DGRAM(UDP) socket_obj socket.socket(socket.AF_INET, socket.SOCK_STREAM)服务器端写法import socket socket_obj socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定地址和端口 socket_obj.bind((127.0.0.1, 8080)) # 开始监听参数5表示最大连接数 socket_obj.listen(5) # 接受客户端连接返回一个新的socket对象和客户端地址信息 accept_socket, client_info socket_obj.accept() # 向客户端发送欢迎信息 accept_socket.send(bWelcome to Socket) # 接收客户端发送的数据1024为缓冲区大小(字节) data accept_socket.recv(1024) # 打印接收到的数据 print(data) # 关闭与客户端的连接 accept_socket.close() # 设置端口号重用 目的是:快速重启服务器(服务器关闭后,立即释放端口) 一般不需要设置这个 # 参1: Socket Level, Socket级别, 即: SOL_SOCKET # 参2: Option Name, 选项名称, 即: SO_REUSEADDR # 参3: Option Value, 选项值, 即: True/False socket_obj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)客户端写法import socket socket_obj socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 客户端连接服务器 socket_obj.connect((127.0.0.1, 8080)) # 接收服务器发送的数据并解码为UTF-8字符串 data socket_obj.recv(1024).decode(utf-8) print(data) # 向服务器发送消息 socket_obj.send(The world is your oyster!.encode(utf-8)) # 关闭连接 socket_obj.close()编解码编码类似加密 解码类似解密只要乱码了 就是解码和编码不一样英文字母数字特殊字符无论什么码都占一个字节中文在gbk中占2个字节utf-8中占3个字节二进制数据特殊写法 即b字母 数字 特殊符号, 该方式对中文无效多线程多任务的概念概念 指的是在同一时间内执行多个任务目的是:充分利用CPU资源 提高程序的执行效率例如 现在电脑安装的操作系统都是多任务操作系统 可以同时允许着多个软件多任务的两种表现形式并发在一段时间内交替执行任务并行:在一段时间内 真正的同时一起执行多个任务进程的概念进程就是CPU资源分配的最小单位它是操作系统进行资源分配和调度运行的基本单位通俗理解: 一个正在运行的程序就是一个进程. 例如:正在运行的QQ,微信等他们都是一个进程使用多线程完成多任务的步骤# 导包 import multiprocessing # 创建子进程并指定执行的任务 sub_process multiprocessing.Process(target任务名) # 启动进程执行任务 if __name__ __main__: sub_process.start()进程传参的两种方式元组方式传参 元组方式传参一定要和任务函数的参数顺序保持一致字典方式传参 字典方式传参字典中的key一定要和任务函数的参数保持一致获取进程的编号概述在设备中, 每个程序(进程)都有自己的唯一进程id当程序释放的时候该进程id也会释放即进程id是可以重复使用的目的查看子进程和父进程的关系方便管理例如:杀死指定进程, 创建子进程格式# 查看当前进程的pid: os模块的getpid() multiprocessing#current_process()的pid属性 ​ # 查看当前进程的ppid: os#getppid()main中创建的进程如果没有特殊规定它的父进程都是main进程而main进程的父进程都是Pycharm程序的pid进程之间不会共享全局变量因为子进程相当于是父进程的副本,会将父进程的main外资源拷贝一份主进程会等待所有的子进程执行结束再结束如果要设置主进程结束子进程同步结束方式如下设置子进程 为守护进程 .daemon()True强制关闭子进程 可能会导致子进程变成僵尸进程 .terminate()线程线程概念线程就是CPU调度的基本单位 每个进程至少都有一个线程而这个线程就是我们通常说的主线程多线程的特点线程执行具有随机性原因是因为CPU在做着高效的切换默认情况下 主线程会等待子线程结束再结束(同一个进程的)线程间 数据共享多线程操作共享数据 可能会出现安全问题 可以用互斥锁解决互斥锁对共享数据进行锁定 保证同一时刻只有一个线程去操作注意:互斥锁是多个线程一起去抢 抢到锁的线程先执行 没有抢到锁的线程进行等待 等锁用完释放后 其它的等待的线程再去抢这个锁 未在合适的时候释放锁会出现死锁# 导包 import threading ​ # 互斥锁的创建 mutex threading.Lock() # 上锁 mutex.acquire() # 释放锁 mutex.release()进程和线程的区别对比维度进程线程基础定义与核心角色操作系统资源分配的基本单位可独立存在CPU调度执行的基本单位必须依附在进程中无进程则无线程数量对应关系一个程序可对应多个进程一个进程默认提供 1 条线程可创建多个线程全局变量共享规则进程之间不共享全局变量线程之间共享全局变量存在资源竞争问题可通过「互斥锁」解决创建与运行资源开销资源开销大资源开销小多核 CPU 利用能力可正常使用多核 CPU无法使用多核 CPUPython 环境下执行独立性可独立执行不能独立执行必须依存于进程中Python 开发稳定性多进程开发稳定性更强单进程多线程开发稳定性相对较弱协程概念协程就是一种可以被挂起 并且在挂起后 还可以恢复执行的函数协程又称微线程 是一种用户态内的上下文切换技术注意: 协程不是操作系统提供的 而是由程序员在用户态 实现的一种切换机制协程函数使用async关键字修饰的函数协程对象调用协程函数 就会得到协程对象import asyncio ​ async def work(): print(work开始) print(work执行中) print(work结束) return 工作结果 ​ # 调用协程函数 会得到协程对象 coroutine_object work() ​ result asyncio.run(coroutine_object) # asyncio.run方法做了3件事情 # 1.创建一个事件循环 # 2.将收到的协程对象 包装成一个任务 交给事件循环 # 3.启动事件循环 # asyncio.run会阻塞当前线程 直到任务执行完毕 并返回该任务 return的最终结果await 关键字的核心作用1 挂起await会暂停当前协程的执行交出控制权2 等待遇到await关键字时事件循环会安排 await 后面的对象去执行并等待其完成同时可以拿到执行结果。执行 await 对象时的两种情况情况一对象中包含 await I/O 操作示例网络请求、文件读写等需要等待外部资源的操作。行为CPU 控制权交给事件循环事件循环会调度执行其他任务实现任务切换。情况二对象中不包含 await I/O 操作示例print 打印、数学计算、逻辑计算等纯CPU操作。行为事件循环无法拿到 CPU 控制权无法调度其他任务不会发生任务切换。3 恢复当 await 后的对象执行完毕事件循环会恢复之前被挂起的协程协程会从挂起的位置继续执行并拿到返回值。重要注意点await 后面只能写可等待对象常见类型包括协程对象Future 对象Task 对象使用协程下载多个图片import asyncio import aiohttp ​ ​ async def down_load(session, url): print(正在下载:, url) # 发送请求 response await session.get(url) content await response.read() # 从URL中提取唯一文件名使用URL中的唯一标识部分 # 例如: D587_D042_0408GT_001.R3D_02599866.jpg filename url.split(material/)[-1].split(.R3D_)[0] .jpg print(filename) with open(filename, wb) as f: f.write(content) await response.release() print(下载完成:, filename) ​ ​ async def main(): url_list [ https://public.ysjf.com/mediastorm/material/material/D587_D042_0408GT_001.R3D_02599866.jpg?x-oss-processimage/resize,w_500, https://public.ysjf.com/mediastorm/material/material/A020_A009_04097I_001.R3D_00229245.jpg?x-oss-processimage/resize,w_500, https://public.ysjf.com/mediastorm/material/material/D580_D015_0109Y5_001.R3D_00433725.jpg?x-oss-processimage/resize,w_500 ] # 创建会话对象(发请求的工具) async with aiohttp.ClientSession() as session: # 创建多个协程对象 coroutine_list [down_load(session, url) for url in url_list] # 将多个协程对象交给事件循环 await asyncio.gather(*coroutine_list) ​ ​ asyncio.run(main())