阶段性知识总结解释版【Day01-Day25】

发布时间 2023-06-19 19:01:18作者: Chimengmeng

day02

1.什么是编程和编程语言

编程
	是指使用计算机语言编写计算机程序的过程。

编程语言
	是一种用于编写计算机程序的形式化语言,它可以被解释器或编译器转换成机器码以便计算机执行。
    编程语言包括C、Java、Python、JavaScript、PHP等。

2.计算机五大组成部分,分别阐释一下各自特点

1.中央处理器(CPU):
	负责执行计算机指令,控制和协调计算机系统中的各个部件。CPU的主要特点
    包括时钟速度、核心数、缓存大小等。

2.存储器(Memory):
	用于存储数据和程序指令, 分为随机存储器(RAM)和只读存储器(ROM)。
    RAM可以快速读写,但是断电会导致数据丢失;而ROM不能进行写操作,但是它的数据可以在断电后保存。

3.输入设备(Input devices):
	用于将外部信息传输到计算机中,如键盘、鼠标、扫描仪、摄像头等。

4.输出设备(Output devices):
	用于从计算机中输出信息,如屏幕、打印机、音响、投影仪等。

5.数据存储设备(Data storage devices):
	用于长期存储数据和程序,如硬盘、固态硬盘(SSD)、U盘、光盘等。

3.计算机三大核心硬件,各自的特点

中央处理器(CPU):
	作为计算机的“大脑”,负责执行指令和控制整个系统。
其主要特点包括时钟频率、核心数、缓存大小等,直接影响计算机的处理能力。

内存(RAM):
	用于临时存储正在运行的程序和数据,是计算机系统中重要的组成部分。
其主要特点包括容量、速度、带宽等,直接影响计算机的运行速度和多任务处理能力。

硬盘(HDD或SSD):
	用于永久性存储数据和文件,是计算机系统中另一个重要的组成部分。
其主要特点包括容量、读写速度、价格等,直接影响计算机的存储能力和数据传输速度。SSD相对于HDD来说读写速度更快,但价格更高。

4.常见的操作系统

Windows操作系统:
	由微软公司开发,广泛用于个人电脑和服务器。

macOS操作系统:
	由苹果公司开发,运行在苹果电脑上。

Linux操作系统:
	一种自由和开放源代码的操作系统,有许多版本可供选择,例如Ubuntu、Debian和Fedora等。

Android操作系统:
	基于Linux内核的移动设备操作系统,由谷歌公司开发。

iOS操作系统:
	由苹果公司开发,运行在iPhone和iPad等移动设备上。

Chrome OS操作系统:
	由谷歌公司开发,主要用于Chromebook笔记本电脑。

Unix操作系统:历史悠久的操作系统,目前仍在许多服务器和大型计算机上使用。

day03

1.计算机存储数据的单位有哪些,之间的单位换算是怎样的

  • 计算机存储数据的单位有以下几种:

    • 位(bit):
      • 是计算机存储的最小单位,它的值可以是0或1,表示二进制的单个数字。位通常用于表示数据的布尔值或编码。
    • 字节(byte):
      • 是计算机中最常用的存储单位,它由8个连续的位组成。
      • 字节用于存储单个字符或一定数量的二进制数据。
      • 在计算机术语中,1字节等于8位。
    • 千字节(kilobyte,KB):
      • 是字节的一种常用单位,1千字节等于1024字节。
      • 虽然"千"字面上表示1000,但在计算机中,通常使用以2为基数的二进制单位。
    • 兆字节(megabyte,MB):
      • 是千字节的一种常用单位,1兆字节等于1024千字节。
    • 吉字节(gigabyte,GB):
      • 是兆字节的一种常用单位,1吉字节等于1024兆字节。
    • 太字节(terabyte,TB):
      • 是吉字节的一种常用单位,1太字节等于1024吉字节。
    • 以上这些单位构成了存储容量的递增序列,用于表示计算机中不同存储容量的数据。
      单位之间的换算通常基于二进制的基数关系,即采用1024作为转换的系数。例如:

1千字节(KB)= 1024字节
1兆字节(MB)= 1024千字节(KB)
1吉字节(GB)= 1024兆字节(MB)
1太字节(TB)= 1024吉字节(GB)

  • 需要注意的是,虽然记忆容量通常使用上述二进制单位,但在某些上下文中,存储容量也可以使用十进制单位(例如1吉字节等于1000兆字节),具体取决于情境和约定。

2.编程语言的发展史,分别有什么特点

  • 编程语言的发展有着悠久的历史,并经历了多个阶段和演变。
    • 下面是编程语言发展史的一些里程碑和特点:
  • 机器语言和汇编语言阶段:
    • 早期的计算机编程使用的是机器语言,它是由0和1组成的二进制代码,直接对应硬件指令。
    • 随后发展出了汇编语言,通过使用更加可读的助记符替代二进制指令来编程。
  • 高级语言阶段:
    • 20世纪50年代末至60年代,高级语言开始出现。
    • 这些语言通过使用更抽象和可读的语法来编写程序,提高了开发效率和可移植性。
  • FORTRAN(1957年):
    • 用于科学计算和数值分析,被认为是第一个高级语言。专注于数值计算和公式表示。
  • LISP(1958年):
    • 用于人工智能研究,以其强大的列表处理和符号操作能力而闻名。
  • COBOL(1959年):
    • 面向商业应用的编程语言,被广泛用于企业应用系统开发。
  • ALGOL(1960年):
    • 在算法和程序结构方面提供了新的语言设计理念,成为高级语言设计的里程碑。
  • BASIC(1964年):
    • 初学者的编程语言,其易学易用的特点促进了计算机的普及和个人计算机的发展。
  • 结构化编程阶段:
    • 在20世纪60年代末到70年代,结构化编程的理念开始流行。
    • 结构化编程强调使用顺序、选择和循环等结构来构建清晰、可读、可维护的代码。
  • C语言(1972年):
    • 由Dennis Ritchie开发,是一种高效、灵活的编程语言。
    • C语言在操作系统和系统编程方面得到广泛应用,并成为其他语言的基础。
  • 面向对象编程阶段:
    • 在20世纪80年代至90年代,面向对象编程(OOP)开始盛行。
    • 面向对象编程通过封装、继承和多态等概念,提供了更加模块化、可重用的编程方法。
  • Smalltalk(1972年):是第一个完全面向对象的编程语言。
    • 它为面向对象编程的原则和理念奠定了基础。
  • C++(1983年):
    • 是在C语言基础上发展起来的一种面向对象编程语言,将面向对象的特性引入到了系统级编程领域。
  • Java(1995年):
    • 是一种跨平台的面向对象编程语言,大量应用于企业级应用开发和桌面应用程序。
  • 脚本语言和动态语言阶段:
    • 20世纪90年代开始,脚本语言和动态语言蓬勃发展,并逐渐流行。
  • Perl(1987年):
    • 脚本语言,专注于字符串处理和文本处理等任务。
  • Python(1991年):
    • 脚本语言,注重代码的可读性和简洁性,广泛应用于Web开发、数据分析和人工智能等领域。
  • Ruby(1995年):
    • 脚本语言,追求简洁和优雅的代码风格,特别受到Web开发者的欢迎。
  • 声明式编程和函数式编程阶段:
    • 近年来,声明式编程和函数式编程成为热门的编程范式。
  • SQL(1974年):
    • 用于数据库操作的领域特定语言,采用声明式编程的风格,通过描述需要的结果,不需指定具体的实现细节。
  • Haskell(1990年):
    • 函数式编程语言,强调纯函数和不可变性,适合处理复杂的数学和逻辑问题。
  • 以上只是编程语言发展史的一些里程碑和特点,并不能穷尽所有的编程语言。
  • 随着技术的不断创新和需求的变化,新的编程语言会不断出现和演进,以满足不同的编程需求。

3.编程语言的分类

  • 编程语言可以根据不同的特性和用途进行分类。下面是根据一些常见的分类方式列举的编程语言的主要分类:

  • 根据执行环境:

    • 编译型语言:
      • 源代码在执行之前需要通过编译器将其转换为可执行的机器代码,例如 C、C++、Go。
    • 解释型语言:
      • 源代码直接由解释器逐行解释执行,无需显式的编译过程,例如 Python、Ruby、JavaScript。
  • 根据应用领域:

    • 通用编程语言:
      • 可用于开发各种类型的应用,例如 C、Java、Python。
    • 领域特定语言(DSL):
      • 专门设计用于特定领域的编程语言,例如 SQL(数据库查询语言)、HTML(网页标记语言)。
  • 根据编程范式:

    • 过程式语言:
      • 侧重于使用过程和函数进行程序设计,例如 C、Fortran。
    • 面向对象语言:
      • 通过对象、类、继承等概念进行程序设计,例如 Java、C++、Python。
    • 函数式语言:
      • 函数是主要的程序构建单元,强调不可变性和无副作用,例如 Haskell、Lisp。
    • 逻辑式语言:
      • 基于逻辑推理进行程序开发,例如 Prolog。
  • 根据支持的编程范式:

    • 单范式语言:
      • 仅支持一种编程范式,例如 C 是过程式语言,Haskell 是纯函数式语言。
    • 多范式语言:
      • 支持多种编程范式,例如 Python、Java 等。
  • 根据使用的编码方式:

    • 非类型语言:
      • 变量类型可以灵活变动,例如 JavaScript。
    • 强类型语言:
      • 对变量类型有严格限制,例如 Java、C++。
    • 弱类型语言:
      • 变量类型可以根据上下文自动转换,例如 PHP。
  • 这些分类仅供参考,实际上,许多编程语言在特性上可能同时涵盖多个分类。

  • 编程语言的选取应根据具体的需求和项目要求来选择最合适的语言。

4.python解释器的版本有哪些,推荐使用的版本是哪个

  • Python 解释器有多个版本可供选择,其中一些主要版本包括:

  • Python 2.x系列:

    • Python 2 是旧版本的 Python,目前最常见的是 Python 2.7。
    • 然而,自2020年1月1日起,Python 2 已经不再维护和支持,因此不推荐使用 Python 2.x。
  • Python 3.x系列:

    • Python 3 是当前主流和推荐使用的 Python 版本。
  • 目前最新的主要版本是 Python 3.9.x,同时也有较稳定版本如 Python 3.8.x 和 Python 3.7.x。Python 3.x 不兼容 Python 2.x 的某些语法和库,但也引入了更多改进和新功能。

  • 对于大多数项目和应用,推荐使用 Python 3.x 的最新稳定版本。

    • 这样可以享受到最新的语言功能和库支持,保持代码的兼容性,并且充分利用社区的支持和贡献。
    • 另外,选择 Python 3.x 还可以避免 Python 2.x 已经停止支持的问题。
  • 需要注意的是,在进行特定项目或与第三方库集成时,可以根据项目要求和库的兼容性要求,选择适当的 Python 版本进行开发和部署。

  • 但总体来说,推荐使用最新稳定版的 Python 3.x。

5.python解释器的多版本共存是怎么做到的,环境变量的查找顺序是如何的

  • 在系统中可以同时安装多个 Python 解释器的版本,并且可以使用特定的工具来管理它们,以实现多个版本的共存。
  • 以下是一种常见的方式来实现多版本共存:
    • 安装不同版本的 Python 解释器:
      • 在系统中分别安装需要的 Python 解释器版本。每个版本的解释器会安装在独立的目录中,以便隔离彼此。
    • 使用虚拟环境(virtual environment):
      • 虚拟环境是一个独立的 Python 运行环境,可以在其中安装和管理特定版本的包和依赖项。
      • 通过创建和激活虚拟环境,可以在每个项目中使用所需的 Python 版本和相关库,而不受系统全局设置的影响。
    • 使用版本管理工具:
      • 使用版本管理工具如 pyenv(Unix-like 系统)或 Anaconda(跨平台)可以方便管理和切换不同版本的 Python 解释器。
  • 关于环境变量的查找顺序,当我们在命令行中输入 python 命令时,系统会按照一定的顺序查找并执行相应的可执行文件。
  • 具体的查找顺序如下:
    • 当前工作目录:
      • 系统首先会在当前工作目录中查找相应的可执行文件并执行。
      • 如果当前工作目录中没有符合条件的文件,则继续执行下一步。
    • 环境变量 PATH:
      • 系统会按照环境变量 PATH 中指定的顺序依次查找目录,并在每个目录中寻找相应的可执行文件。
      • 当找到第一个匹配的可执行文件时,系统会执行该文件。
      • 如果在 PATH 中的所有目录中都找不到符合条件的文件,则会报错提示找不到命令。
  • 需要注意的是,环境变量 PATH 中的目录顺序非常重要。
    • 如果某个命令存在于多个目录下,那么在 PATH 中排在前面的目录下的命令会被优先执行。
  • 在多版本共存的情况下,可以通过合理配置 PATH 环境变量和使用虚拟环境的方式来确保使用所需的 Python 解释器版本。

day04

1.如何书写python的注释语法

  • Python 中的注释语法有两种,分别是单行注释和多行注释。

    • 单行注释

      • 在 Python 中,用 # 符号表示单行注释,在其后面加上注释内容即可。例如:
    • 这是一个单行注释

      • 如果要注释一段代码,可以通过在行首加上 # 符号来实现:
x = 1  # 给变量 x 赋值为 1
  • 多行注释

    • 在 Python 中,用 ''' 或 """ 来表示多行注释。例如:
"""
这是一个多行注释
可以有多行
"""
  • 或者:
'''
这也是一个多行注释
可以用单引号
'''
  • 多行注释通常用于文档字符串,即用于为函数、模块、类等对象编写文档的字符串注释。
  • 需要注意的是,Python 中没有多行注释的嵌套,如果需要在多行注释中再使用多行注释,需要使用新的一组 ''' 或 """。

2.变量的基本使用,以及底层原理

  • 变量是用于存储和引用数据的名称,可以通过变量名来访问和操作数据。

    • 在 Python 中,变量的基本使用包括声明和初始化变量、修改变量的值和使用变量进行计算等。
  • 声明和初始化变量:

    • 在 Python 中,变量不需要显式地声明,可以直接使用赋值语句初始化变量。
var_name = value

其中,var_name 是变量名,可以自定义,value 是要存储在变量中的数据。

  • 修改变量的值:
    • 可以通过赋值语句来修改变量的值。
var_name = new_value

这样会将新的值存储在变量中,覆盖原来的值。

  • 使用变量进行计算:

    • 变量可以参与各种数学运算和逻辑操作。
a = 5
b = 3
c = a + b

在上述示例中,变量 a 和 b 分别赋值为 5 和 3,然后将它们相加并将结果存储在变量 c 中。

  • 底层原理:
    • 在底层,Python 中的变量是一个名字和一个指向内存地址的引用的组合。
    • 通过变量名,程序可以访问和操作保存在内存中的数据。
    • 当我们进行变量赋值时,实际上是将数据存储在内存中的某个位置,并将变量名与该位置关联起来。
    • 当使用变量时,Python 通过变量名查找对应内存地址中存储的数据。
    • 由于变量是动态类型的,可以存储不同类型的数据,并且可以在运行时更改变量的类型和值。
    • 需要注意的是,Python 的变量是引用传递,即变量保存的是数据的引用(内存地址),而非数据本身。
    • 当一个变量被赋予另一个变量时,两个变量实际上引用的是同一个数据。
    • 当对一个变量进行修改时,另一个变量也会受到影响。
    • 在变量使用中,需要注意变量的作用域和生命周期等概念,以确保正确的数据访问和管理。

3.变量的命名规范

  • 在 Python 中,变量的命名需要遵循一定的规范,以提高代码的可读性和可维护性。以下是一些常用的变量命名规范:

    • 使用有意义的变量名:

      • 变量名应该能够清楚地描述变量的含义和作用。
      • 避免使用单个字符或无意义的命名。
    • 使用小写字母和下划线:

      • 变量名应该使用小写字母,并用下划线 _ 分隔单词,这样可以提升变量名的可读性,如 student_name, age_of_person。
    • 避免使用 Python 的关键字作为变量名:

      • Python 中有一些关键字用于表示特定的功能或语法结构,不能用作变量名。
      • 关键字包括 if, for, while, def, class 等,请避免使用它们作为变量名。
    • 注意命名的一致性和规范:

      • 在一个项目中,保持变量命名的一致性,使用相同的风格和命名习惯。
      • 遵循团队或项目所采用的命名规范。
    • 避免使用缩写和简写:

      • 变量名应该尽量保持简洁,但又要具备足够的描述性。
      • 避免使用过多的缩写或简写,以免导致不易理解和维护的情况。
    • 注意使用匈牙利命名法(Hungarian Notation):

      • 匈牙利命名法是一种命名约定,可以在变量名中添加前缀以指示变量的数据类型或其他特征。
      • 在 Python 中,通常不需要使用匈牙利命名法,因为 Python 是动态类型语言。
  • 综上所述,变量的命名规范旨在提高代码的可读性和可维护性。遵循命名规范可以使代码更易于理解、调试和扩展。

4.python中的常量如何定义以及特点

  • 在 Python 中,常量是不可变的值,其值在定义后不能被修改。
    • Python 并没有内置的常量类型,但通常使用全大写字母命名的变量来表示常量,并将其值保持不变。
  • 以下是在 Python 中定义常量的方式和其特点:
    • 使用变量来表示常量:
      • 在 Python 中,可以使用变量来表示常量,并约定不对其进行修改。
      • 通常使用全大写字母命名的变量来表示常量,以便在代码中明确标识。
MY_CONSTANT = 100
  • 习惯上不修改常量的值:
    • 虽然 Python 中的常量是可以修改的,但是出于习惯上的考虑,通常将常量的值设置为不可变类型(如整数、字符串、元组等),并不对其进行修改。
MY_CONSTANT = 100  # 不修改常量的值
  • 不推荐修改常量的值,但是可以改变其引用
MY_CONSTANT = MY_CONSTANT + 1  # 修改常量的引用
  • 不推荐修改常量的值,但是可以修改其属性(如果是可变类型)
MY_CONSTANT_LIST = [1, 2, 3]
MY_CONSTANT_LIST.append(4)  # 修改常量的属性
  • 没有固定的语法机制:

    • Python 并没有提供内置的语法机制来定义常量,因此,变量名的约定是实现常量概念的重要方式。
  • 常量是约定而非强制:

    • 尽管约定了使用全大写命名的变量表示常量,但实际上 Python 并不会强制禁止对常量进行修改。
    • 这是一种约定俗成的惯例,旨在提醒开发者不要轻易修改变量。
  • 需要注意的是,虽然在 Python 中没有严格意义上的常量类型,但是可以通过编程规范和约定来达到相同的效果。

    • 同时,还要留意特定库和框架中是否存在特定的常量定义方式和机制,以满足特殊需求。

5.垃圾回收机制

  • 垃圾回收是一种自动内存管理技术,它的目标是检测和释放不再使用的内存,以避免内存泄露和优化内存使用。
    • 在编程中,当一个对象被创建时,它会占用一定的内存空间。
    • 但是,当这个对象不再需要时,我们需要将其占用的内存释放掉,以便其他对象可以使用这些内存空间。这个过程就是垃圾回收的核心任务。
  • 不同的编程语言和环境有不同的垃圾回收机制。下面是一些常见的垃圾回收机制:
    • 引用计数:
      • 这是一种简单的垃圾回收机制。
      • 它跟踪每个对象被引用的次数,当对象的引用计数为零时,就可以释放它占用的内存。
      • 缺点是无法解决循环引用的问题,即两个或多个对象相互引用,但没有其他对象引用它们。
    • 标记-清除:
      • 这是一种基于可达性分析的垃圾回收算法。
      • 它通过从根对象开始,递归地标记出所有可达的对象,然后清除不可达的对象。
      • 这个过程会涉及遍历整个堆内存,标记和清除的效率较低。
    • 分代回收:
      • 这是一种基于对象存活时间的垃圾回收策略。
      • 根据对象的存活时间将内存分为不同的代,一般是将内存分为 young generation 和 old generation。
      • 新创建的对象首先分配到 young generation,其回收是频繁的。
      • 长时间存活的对象会被晋升到 old generation,它们的回收相对较少。
    • 增量式回收:
      • 为了减少垃圾回收造成的卡顿,增量式回收将垃圾回收过程分成多个阶段。
      • 每个阶段只回收一部分可达对象,然后暂停一小段时间让程序继续运行,再执行下一阶段的回收。
      • 这样可以分散回收的时间,减小对程序执行的影响。
  • 垃圾回收机制的具体实现会因语言和运行环境的不同而有所差异。
  • 开发人员可以根据具体的需求和场景选择合适的垃圾回收策略,以优化内存的使用和性能。

day05

1.列举你所知道的python所有基本数据类型及各自特征

  • Python 中的基本数据类型包括以下几种:

  • 整数 (int):

    • 表示整数,即不带小数部分的数值。
    • 特征:
      • 整数类型的数据没有大小限制,可以是正数、负数或零。
  • 浮点数 (float):

    • 表示带有小数部分的数值。
    • 特征:
      • 浮点数可以表示大范围的有理数,但由于浮点数的精度有限,可能会引入一些舍入误差。
  • 布尔值 (bool):

    • 表示真(True)或假(False)两个值。
    • 特征:
      • 布尔值常用于条件判断和逻辑运算,其结果只有 True 或 False 两种可能。
  • 字符串 (str):

    • 表示由字符组成的文本。
    • 特征:
      • 字符串是不可变的,即不能在原地修改字符串的值。字符串可以使用单引号或双引号括起来。
  • 列表 (list):

    • 表示有序的可变容器,可以存储不同类型的元素。
    • 特征:
      • 列表使用方括号 [] 表示,可以通过索引访问元素。列表的长度和元素可以在运行时改变,支持增加、删除和修改元素。
  • 元组 (tuple):

    • 表示有序的不可变容器,可以存储不同类型的元素。
    • 特征:
      • 元组使用圆括号 () 表示,不同于列表,元组的元素不可被修改,即为不可变类型。
  • 集合 (set):

    • 表示无序、不重复的集合。
    • 特征:
      • 集合使用大括号 {} 表示,集合中的元素没有顺序,且不允许重复。可以用于快速地进行成员检查和消除重复元素。
  • 字典 (dict):

    • 表示键值对的映射关系。
    • 特征:
      • 字典使用大括号 {} 表示,每个键值对用冒号 : 分隔,键和值之间用逗号 , 分隔。字典中的键必须是唯一的且不可变,而值可以是任意类型。
  • 除了上述基本数据类型,Python 还提供了其他高级数据类型,如日期时间 (datetime)、集合(set)、字节串(bytes)等。这些数据类型各自有不同的特征和用途,可以根据需要选择适当的类型来存储和操作数据。

2.什么是格式化输出,如何使用

  • 格式化输出是指将变量、表达式或其他数据以特定格式输出到屏幕或文件中。

    • 在 Python 中,常用的格式化输出方法有两种:
      • 使用百分号 (%) 运算符进行格式化输出
      • 使用字符串的 format() 方法进行格式化输出。
  • 使用百分号 (%) 运算符进行格式化输出:

    • 使用百分号 (%) 运算符可以将变量或表达式插入到字符串中,并指定输出的格式。
name = "Alice"
age = 25

print("My name is %s and I am %d years old." % (name, age))

上述代码中,

​ %s 表示插入字符串,

​ %d 表示插入整数。

在字符串后面的 % 后面,跟着的对象是一个元组,元组中包含了要插入的变量或表达式。

当使用 %s 时,可以插入任何类型的对象,而 %d 仅用于整数类型。

  • 使用字符串的 format() 方法进行格式化输出:
    • format() 方法是一种更加灵活和易读的格式化输出方式
    • 它使用花括号 {} 作为占位符。
name = "Alice"
age = 25

print("My name is {} and I am {} years old.".format(name, age))

在上述代码中

​ 用花括号 {} 表示占位符

​ format() 方法会根据占位符的顺序将变量或表达式插入到字符串中。

可以在花括号中添加一些特定的标记来指定输出的格式

​ 如 {:d} 表示插入的是一个整数。

  • 除了上述两种常用的方法外
    • Python 还提供了一种新的格式化输出方式,即 f-string(在 Python 3.6 版本及以上可用)。
    • 它以 f 或 F 作为前缀,将变量或表达式包含在大括号 {} 中。
name = "Alice"
age = 25

print(f"My name is {name} and I am {age} years old.")
  • 使用 f-string 可以在大括号中直接引用变量或表达式,在大括号内部可以使用任何有效的 Python 表达式。
  • 这些方法都提供了一种灵活和方便的方式来对数据进行格式化输出,以满足不同的需求。
    • 可以根据具体的需求选择最适合的方法进行格式化输出。

3.说说你所知道的运算符有哪些

  1. 算术运算符:
    • +:相加
    • -:相减
    • *:相乘
    • /:相除(得到浮点数)
    • //:相除取整(得到整数)
    • %:取模(取余数)
    • **:幂运算
  2. 比较运算符:
    • ==:等于
    • !=:不等于
    • >:大于
    • <:小于
    • >=:大于等于
    • <=:小于等于
  3. 逻辑运算符:
    • and:逻辑与
    • or:逻辑或
    • not:逻辑非
  4. 赋值运算符:
    • =:赋值
    • +=:加后赋值
    • -=:减后赋值
    • *=:乘后赋值
    • /=:除后赋值
    • //=:除后取整赋值
    • %=:取模后赋值
    • **=:幂运算后赋值
  5. 位运算符:
    • &:与运算
    • |:或运算
    • ^:异或运算
    • ~:取反
    • <<:左移运算
    • >>:右移运算
  6. 成员运算符:
    • in:存在于
    • not in:不存在于
  7. 身份运算符:
    • is:身份是否相同
    • is not:身份是否不同

day06

1.成员运算与身份运算各自功能

  • 成员运算符和身份运算符是 Python 中的两种不同的运算符,它们具有不同的功能。

  • 成员运算符 (Membership Operators) 用于判断一个值是否存在于一个集合 (如列表、元组、字符串等) 中。

  • in 运算符会在集合中查找给定的值,如果存在则返回 True,否则返回 False。

    • 示例:
my_list = [1, 2, 3, 4, 5]
print(3 in my_list)  # 输出 True
print(6 in my_list)  # 输出 False
  • not in 运算符与 in 运算符相反,如果给定的值不存在于集合中,则返回 True,否则返回 False。

    • 示例:
my_list = [1, 2, 3, 4, 5]
print(3 not in my_list)  # 输出 False
print(6 not in my_list)  # 输出 True
  • 成员运算符可以用于各种集合以及字符串等,判断给定的值是否存在于这些集合中。

  • 身份运算符 (Identity Operators) 用于比较两个对象的身份标识 (即内存地址) 是否相等。

  • is 运算符会比较两个对象的身份标识,如果两个对象具有相同的身份标识,则返回 True,否则返回 False。

    • 示例:
a = [1, 2, 3]
b = a
print(a is b)  # 输出 True
  • is not 运算符与 is 运算符相反,如果两个对象具有不同的身份标识,则返回 True,否则返回 False。

    • 示例:
a = [1, 2, 3]
b = [1, 2, 3]
print(a is not b)  # 输出 True
  • 身份运算符用于比较对象之间的身份标识,即内存地址是否相同。它们可以确定两个变量是否指向同一个对象。

总结:

成员运算符 (in, not in) 用于检查一个值是否存在于一个集合中。

身份运算符 (is, is not) 用于比较两个对象的身份标识 (内存地址) 是否相等。它们确定两个变量是否指向同一个对象。

2.if判断的三种语法结构及必备知识点如何代码缩进等

  • 在 Python 中,if 判断语句用于根据条件的真假来执行不同的代码块。以下是 if 判断的三种语法结构以及必备知识点:

    • 单个 if 语句结构:
if condition:
    # 执行满足条件时的代码块

condition 是一个返回布尔值的表达式,如果条件为 True,则执行紧随其后的缩进块中的代码。

  • if-else 语句结构:
if condition:
    # 执行满足条件时的代码块
else:
    # 执行条件不满足时的代码块

当 condition 为 True 时,执行第一个缩进块中的代码;否则,执行 else 后面的缩进块中的代码。

  • if-elif-else 语句结构:
if condition1:
    # 执行满足 condition1 条件时的代码块
elif condition2:
    # 执行满足 condition2 条件时的代码块
else:
    # 执行条件均不满足时的代码块

当 condition1 为 True 时,执行第一个缩进块中的代码;否则,检查 condition2。如果 condition2 为 True,则执行第二个缩进块中的代码;否则,执行 else 后面的缩进块中的代码。

  • 在 Python 中,代码的缩进非常重要,它用于标识代码块的层次结构。相同缩进级别的代码块视为同一代码块,缩进通过四个空格或者一个制表符来表示。注意以下几点:

    • 嵌套的代码块必须拥有相同的缩进级别。
    • Python 中使用冒号来表示代码块的开始。
    • 在所有的语法结构中都必须遵循正确的缩进规则,否则代码会导致语法错误。
  • 示例:

if condition1:
    print("条件1成立")
elif condition2:
    print("条件2成立")
else:
    print("条件均不成立")

需要注意的是,if 语句可以嵌套或与其他语句结合使用,以满足复杂的逻辑需求。同时了解布尔表达式和比较运算符在条件中的使用也是必备知识点之一。

3.while循环语法结构

  • 在 Python 中,while 循环用于重复执行一段代码,直到给定条件变为假为止。
    • 以下是 while 循环的语法结构:
while condition:
    # 在条件为真时执行的代码块

condition 是一个返回布尔值的表达式,当条件为 True 时,循环会一直执行代码块中的代码。只要条件保持为真,循环会一直运行下去,直到条件变为假或者遇到 break 语句才会停止循环。

  • 在循环中,代码块中的语句会被重复执行,直到条件不再满足为止。
    • 为了避免无限循环,需要确保在合适的时候修改条件,否则循环将一直执行下去。
    • 在循环中,可以使用适当的循环控制语句(如 break 或 continue)以及合适的计数器或其他条件来控制循环的终止条件。
  • 示例:
count = 0
while count < 5:
    print("当前计数: ", count)
    count += 1
  • 在上述示例中,循环会一直执行,打印出当前的计数,直到计数达到 5,才会停止循环。
  • 需要注意的是,当设计循环时,要确保循环条件能够在某个时刻变为 False,否则可能会导致无限循环。
    • 同时,循环体内的代码块需要适当缩进,并遵循缩进规则。

day07

编写⽤户登录程序
温馨提示:
⽤户名与密码来源于字符串source_data = 'kevin|123'
想办法从中拆分出⽤户名和密码⽤于后续账户信息⽐对
普通要求:
1.验证失败情况下可⼀直循环验证 成功则直接退出
拔⾼练习:
1.只允许三次失败机会
2.登录成功后进⼊内层循环,⽤户输⼊任何指令利⽤格式化输出
打印正在执⾏该⽤户指令即可,直到⽤户输⼊字⺟q退出内层循环

# 普通要求实现:
source_data = 'kevin|123'
user_name, password = source_data.split('|')

while True:
    input_name = input('请输入用户名:')
    input_password = input('请输入密码:')
    if input_name == user_name and input_password == password:
        print('登录成功!')
        break
    else:
        print('用户名或密码错误,请重新输入。')

# 拔高练习实现:
source_data = 'kevin|123'
user_name, password = source_data.split('|')

failure_count = 0
while True:
    if failure_count == 3:
        print('登录失败次数达到上限,程序退出。')
        break
    input_name = input('请输入用户名:')
    input_password = input('请输入密码:')
    if input_name == user_name and input_password == password:
        print('登录成功!')
        while True:
            command = input('请输入指令(输入 q 退出):')
            if command == 'q':
                print('退出指令输入,程序结束。')
                break
            else:
                print('正在执行【{}】指令...'.format(command))
        break
    else:
        failure_count += 1
        print('用户名或密码错误,请重新输入。您还有 %s 次机会。' % (3 - failure_count))
  • 该代码分为两个部分
    • 第一部分和普通要求中的代码类似,判断用户名和密码是否正确。
    • 如果正确,进入第二部分的循环体中,开始接受指令,直到用户输入 q 命令退出循环体并终止程序执行。
    • 在第一部分中,我们使用一个 failure_count 变量来记录用户已经尝试登录失败的次数,在 3 次登录失败之后,程序自动结束。
    • 在第二部分中,我们使用一个嵌套的 while 循环来接收指令,直到用户输入 q 命令。

day08

1.列举字符串至少五个你认为较为重要的方法

  • split(sep=None, maxsplit=-1):

    • 将字符串分割成一个列表。
    • sep 参数指定分隔符,默认为任何空白字符。
    • maxsplit 参数指定要分割的次数。
  • join(iterable):

    • 使用字符串连接给定的可迭代对象中的元素。
  • lower():

    • 将字符串中的字母转换为小写。
  • upper():

    • 将字符串中的字母转换为大写。
  • replace(old, new[, count]):

    • 将字符串中的指定旧字符串替换为新字符串。可选择指定替换的次数。

2.列举列表如何修改值,添加值,删除值的方法

  • 列表是一种可变的数据类型,提供了多种方法来修改、添加和删除其中的值。以下是几种常用的方法:

  • 修改值:

    • 可以通过索引直接访问列表中的元素,并进行修改。
  • 示例:

my_list = [1, 2, 3, 4, 5]
my_list[2] = 10  # 修改索引为2的元素,将其设置为10
print(my_list)  # 输出 [1, 2, 10, 4, 5]
  • 添加值:

    • 可以使用 append() 方法将元素添加到列表的末尾。
  • 示例:

my_list = [1, 2, 3]
my_list.append(4)  # 在列表末尾添加元素4
print(my_list)  # 输出 [1, 2, 3, 4]
  • 在指定位置添加值:
    • 可以使用 insert() 方法在指定的索引位置添加元素。
  • 示例:
my_list = [1, 2, 3]
my_list.insert(1, 10)  # 在索引为1的位置添加元素10
print(my_list)  # 输出 [1, 10, 2, 3]
  • 删除值:

    • 可以使用 del 关键字、remove() 方法或者 pop() 方法来删除列表中的元素。
  • 使用 del 关键字可以通过索引删除元素。

  • 示例:

my_list = [1, 2, 3, 4, 5]
del my_list[2]  # 删除索引为2的元素
print(my_list)  # 输出 [1, 2, 4, 5]
  • 使用 remove() 方法可以通过元素的值删除元素。
    • 如果列表中有重复的元素,它只会删除第一个匹配项。
  • 示例:
my_list = [1, 2, 3, 2, 4]
my_list.remove(2)  # 删除值为2的元素
print(my_list)  # 输出 [1, 3, 2, 4]
  • 使用 pop() 方法可以通过索引删除元素
    • 并返回被删除的元素。
  • 示例:
my_list = [1, 2, 3, 4]
removed_element = my_list.pop(1)  # 删除索引为1的元素,并返回被删除的元素
print(removed_element)  # 输出 2
print(my_list)  # 输出 [1, 3, 4]
  • 这些是列表中常用的一些修改、添加和删除元素的方法,可以根据需求选择适当的方法来操作列表。

3.用自己的话概括什么是可变类型与不可变类型

  • 可变类型和不可变类型是对于变量值的修改而言的。

    • 可变类型 (Mutable): 在改变变量值时,内存中的值可以被修改。修改后,变量仍然指向相同的内存地址。

      • 例如:列表 (list)、字典 (dictionary) 和集合 (set) 等是可变类型。
      • 对于可变类型的变量,在进行修改操作时,不会创建新的对象。
    • 不可变类型 (Immutable): 在改变变量值时,需要创建一个新的对象来存储修改后的值。修改后的变量会指向新的内存地址。

      • 例如:整数 (integer)、浮点数 (float)、布尔值 (boolean)、元组 (tuple) 和字符串 (string) 等是不可变类型。
      • 对于不可变类型的变量,在进行修改操作时,会创建一个新的对象。
  • 要注意的是,即使一个对象是可变的,它的身份标识(内存地址)也是不可变的。

    • 比如,在修改列表的元素时,列表的身份标识不会改变,但是修改字符串的某个字符时,字符串的身份标识会改变。
    • 这是因为字符串是不可变类型,修改某个字符会创建一个新的字符串对象。
  • 总之

    • 可变类型的值可以在原地进行修改
    • 而不可变类型的值则需要创建新的对象来存储修改后的值。
    • 在使用可变类型和不可变类型时,需要根据需求考虑其特性和行为。

小练习

# 统计每个单词的个数
# 原始数据:
s1 = 'kevin say hello hello hello big baby baby baby sb sb kevin kevin'
# 1. 按空格将每个字符串切分到列表里
names_list = s1.split(' ')
# 以字典形式记录每个名字出现的次数:name:count
name_count = {}
# 循环遍历列表,将次数记录到字典里
for name in names_list:
    # 如果名字不在字典里就添加进去名字,并且次数记 1
    if name not in name_count:
        name_count[name] = 1
    # 如果名字存在在字典里就名字次数 + 1
    else:
        name_count[name] += 1
# 打印统计次数的字典
print(name_count)
# {'baby': 3, 'big': 1, 'hello': 3, 'kevin': 3, 'say': 1, 'sb': 2}
# -----------------------------上为第一题 分割线 下为第二题-----------------------------------------#
# 统计每个字符的个数(原理同上)
# 原始数据
text = 'kevinsayhello'
code_dict = {}
for i in text:
    if i not in code_dict:
        code_dict[i] = 1
    edaylse:
        code_dict[i] += 1
print(code_dict)
# {'k': 1, 'e': 2, 'v': 1, 'i': 1, 'n': 1, 's': 1, 'a': 1, 'y': 1, 'h': 1, 'l': 2, 'o': 1}

day09

1.什么是元组,能否用文字详细描述一下,在定义元组时有何注意事项

  • 元组(Tuple)
    • 指的是一种不可变(即不可修改、添加或删除元素)的有序序列,其可以包含多个不同的数据类型,如整数、浮点数、字符串、元组等。
    • 可以将元组视为列表(List)或数组(Array)的不可变版本,也可以理解为字典(Dictionary)的键值对。
    • 元组的每个元素都可以通过其下标访问,而它们本身则通过括号来标识,元素之间用逗号分隔。
    • 以下是一个元组的示例:
tuple1 = (1, 2, 'hello', 4.5, (5, 6))
  • 在定义元组时,需要注意以下几点:

    • 元组中可以包含多个元素,每个元素之间用逗号分隔。
    • 元组中的元素可以为不同的数据类型
      • 如整数、浮点数、字符串、元组等。
    • 元组是不可变的,即元组中的元素不能被修改、添加或删除。
      • 如果需要修改元素,需要先将其转为可变类型(如列表),修改完之后再将其转为元组。
    • 在定义元组时,可以使用小括号或不加括号的形式。
      • 例如,tup = 1, 2, 3 与 tup = (1, 2, 3) 表示的是同一个元组。
    • 在定义只包含一个元素(单元素元组)的元组时,必须在元素后面添加一个逗号,否则会被视为普通的括号,而不是元组。
      • 例如,tup = (1, ) 表示的是一个包含一个元素的元组,而不是一个数字 1。
    • 元组的元素可以通过下标(索引)来访问,从 0 开始计数。
      • 例如,对于上面的元组,要访问其中的第一个元素,可以使用 tuple1[0]
  • 总之,元组是一种简单、不可变的数据结构,通常用于存储不可修改的数据,如坐标、配置信息等。

  • 在定义元组时需要注意元素之间的格式和逗号的使用,同时需要注意元组不支持修改,若需要修改元素,应该先转成可变类型进行修改。

2.什么是集合,主要功能有哪些,如何实现这些功能

  • 集合(Set)是 Python 中的一种基本数据类型,它是一种无序、不重复的序列。
    • 和列表(List)和元组(Tuple)类似,集合也可以包含任意类型的数据,但与列表和元组不同的是,集合中的元素是唯一的,即不会出现重复的元素。
    • 集合在 Python 中的定义方式为用花括号 {} 将所有的元素括起来,并用逗号隔开,例如:
myset = {1, 2, 3, 4, 5}
  • 集合的主要功能包括以下几个方面:

    • 去重。
      • 集合中的元素是唯一的,它可以帮助我们快速地完成去重的操作。
    • 成员检查。
      • 可以快速地判断一个元素是否在集合中。
    • 交集、并集、差集操作。
      • 可以实现两个集合的交集、并集以及差集等操作。
    • 集合的增删改查。
      • 集合是可变数据类型,可以实现增加、删除等操作。
  • 在 Python 中,集合是使用哈希表来实现的。

    • 哈希表是一种基于数组的数据结构,它可以将任意元素映射为数字索引,同时支持快速查找、插入和删除操作。
    • 对于集合中的元素,Python 会使用哈希函数将其映射为索引,这样就可以快速地完成集合操作。
    • 具体实现方式可以使用 set()函数来创建集合,以及使用一系列的内置函数(如 add()、remove()、pop() 等)来实现集合的增删改查操作。
  • 以下是一些常见的集合操作实现方式:

去重。

​ 可以直接使用 set() 函数来创建一个集合,重复的元素会自动限制,例如:

mylist = [1, 2, 2, 3, 3, 4, 5]
myset = set(mylist)
print(myset)  # 输出:{1, 2, 3, 4, 5}

成员检查。

​ 可以使用 in 和 not in 运算符来检查一个元素是否在集合中,例如:

myset = {1, 2, 3, 4, 5}
if 4 in myset:
    print('4 在集合中')
else:
    print('4 不在集合中')

交集、并集、差集操作。

​ 可以使用 &、|、- 运算符分别表示两个集合的交集、并集和差集,例如:

set1 = {1, 2, 3, 4, 5}
set2 = {3, 4, 5, 6, 7}

交集

print(set1 & set2)  # 输出:{3, 4, 5}

并集

print(set1 | set2)  # 输出:{1, 2, 3, 4, 5, 6, 7}

差集

print(set1 - set2)  # 输出:{1, 2}

集合的增删改查。可以使用一系列内置函数来实现集合的增、删、改、查等操作,例如:

myset = {1, 2, 3, 4, 5}

增加元素

myset.add(6)
print(myset)  # 输出:{1, 2, 3, 4, 5, 6}

删除元素

myset.remove(4)
print(myset)  # 输出:{1, 2, 3, 5, 6}

随机删除一个元素

myset.pop()
print(myset)  # 输出:{2, 3, 5, 6}

清空集合

myset.clear()
print(myset)  # 输出:set()
  • 总之,集合是一种常用的数据类型,它能够帮助我们轻松实现去重、成员检查、集合操作等功能。集合使用哈希表实现,因此具有高效的性能。+
  • 在使用集合的时候,需要注意其无序性和不可重复性,以及使用其内置函数实现集合的增删改查操作。

3.列举字典常用内置方法

  • 字典(Dictionary)是 Python 中非常常用的数据类型之一,它也是一个哈希表(Hash Table)结构,用于存储键值对。字典有许多内置方法(Builtin Methods),以下是一些常用的内置方法:

  • clear()

    • 清空字典。
  • copy()

    • 复制字典,返回一个浅复制的新字典。
  • fromkeys(keys, value=None)

    • 创建一个新字典,以序列 keys 中的元素作为字典的键,所有键对应的初始值都设置为 value。
  • get(key, default=None)

    • 返回键 key 对应的值,如果不存在则返回默认值 default 或者 None。
  • items()

    • 返回字典的键值对(Items)。
  • keys()

    • 返回字典的所有键(Keys)。
  • pop(key, default=None)

    • 返回键 key 对应的值,并将其从字典中删除,如果不存在则返回默认值 default 或者抛出 KeyError 错误。
  • popitem()

    • 随机弹出字典中的一对键值(Key-Value)。
  • setdefault(key, default=None)

    • 返回键 key 对应的值,如果不存在则将其设置为默认值 default。
  • update([other])

    • 更新字典,将另一个字典 other 或者键值对集合更新至原字典中。
  • values()

    • 返回字典的所有值(Values)。
  • 注意:以上内置方法的调用方式均为 dict.method() 的形式,其中 dict 指代字典本身。

  • 这些方法可以帮助我们方便地查询、增加、删除、更新字典中的键值对,使得字典变得更加灵活、易用、高效。

4.有一个字符串‘ababaccdd’,如何统计每个字符出现的个数并组织成字典的形式展示出来如{‘a’:3}(尝试手写代码实现)

# 可以使用 Python 字典来统计每个字符出现的次数,具体实现如下:
s = 'ababaccdd'
d = {}

# 遍历字符串
for c in s:
    # 判断字符 c 是否在字典中出现过
    if c in d:
        # 如果出现过,则计数加一
        d[c] += 1
    else:
        # 如果没出现过,则将其初始计数设置为 1
        d[c] = 1

# 输出字典
print(d)

# 代码输出结果为:
{'a': 3, 'b': 2, 'c': 2, 'd': 2}
这段代码中
	我们首先定义了一个字符串变量 s,然后定义了一个空字典 d,用于存储每个字符出现的次数。
接着,我们遍历字符串中的每个字符。
	对于每个字符,如果它已经在字典中出现过,那么我们就将它出现的次数加一;
	如果它没有在字典中出现过,那么我们就将它的初始计数设置为 1,将其作为一个键值对放入字典中。
最终,输出统计出来的字典结果。
	可以发现,最终的字典中,键表示每个出现过的字符,值表示该字符在字符串中出现的次数。

day10

1.针对员工管理系统,请详细写出添加员工信息的代码逻辑(语言表述)

假设我们的员工管理系统使用 Python 实现,在添加员工信息时,可以按照以下代码逻辑:

首先,使用 input 函数获取用户输入的员工信息,包括姓名、年龄、性别、职位等,将其存入相应的变量中。
在将员工信息存入系统之前,需要对用户输入进行校验。例如,对年龄进行数字校验,确保其是正整数。
接下来,需要创建一个员工信息列表,用于存储系统中所有员工的信息,可以使用 Python 中的列表数据结构。
将用户输入的员工信息封装成一个字典对象,包括姓名、年龄、性别、职位等信息,并将该字典对象添加到员工信息列表中。
最后,输出添加成功的提示信息,并返回员工信息列表,为后续操作提供基础。

可能的 Python 语言表述如下:
# Step 1: 获取用户输入
name = input("请输入员工姓名:")
age = input("请输入员工年龄:")
gender = input("请输入员工性别:")
position = input("请输入员工职位:")

# Step 2: 对用户输入进行校验
if not age.isdigit() or int(age) <= 0:
    print("错误的年龄输入,请重新输入!")
    # 可以加上重复输入的操作,直至输入正确为止

# Step 3: 创建员工信息列表
staff_list = []

# Step 4: 将用户输入的员工信息封装成字典,并添加到员工信息列表中
staff_dict = {'name': name, 'age': int(age), 'gender': gender, 'position': position}
staff_list.append(staff_dict)

# Step 5: 输出成功提示信息,并返回员工信息列表
print("员工信息添加成功!")
return staff_list

当然,上述代码仅为一种示例,实际开发中还需要考虑并处理更多的错误情况,例如输入的员工信息不完整、重复添加员工信息、写入员工信息到文件系统等情况。

2.什么是字符编码表,你都知道哪些,特点各自有何

  • 字符编码表(Character Encoding)用于将字符映射到数字编码,以方便计算机处理,其中最为常见的字符编码表包括 ASCII、ISO-8859、GB2312、GBK、UTF-8 等。这些编码表都用于将字符映射为数字编码,但它们的特点和使用情况有所不同。

  • ASCII

    • 美国信息交换标准代码(American Standard Code for Information Interchange,简称 ASCII)是一种基于拉丁字母的字符编码表,将字母、数字、标点符号等常见符号映射到不同的数字编码。
    • ASCII 编码采用 7 位二进制数(即 2 的 7 次幂,共计 128 种字符编码),能够表示的字符数量有限,主要用于英语、拉丁字母编写的文本数据。
  • ISO-8859

    • 国际标准组织(ISO)制定了一系列的字符编码表,最为常见的是 ISO-8859,也称为拉丁语系字符编码表(Latin Character Encoding)。
    • ISO-8859 包含多种编码表,如 ISO-8859-1、ISO-8859-2 等,每种编码表针对不同的语言或国家,将拉丁字母以及其他特殊字符映射到不同的数字编码。
    • 与 ASCII 不同的是,ISO-8859 采用 8 位二进制数(即 2 的 8 次幂,共计 256 种字符编码),能够表示更多的字符,主要用于欧洲国家和语言。
  • GB2312

    • GB2312 是中国采用的中文编码表,将汉字以及常用的符号、数字、字母等映射到不同的数字编码,采用 2 字节表示一个汉字。GB2312 能够表示约 7,000 个常用中文字符,满足了汉字的基本需求,但只能覆盖中文汉字及其部分符号,建立在 ASCII 基础上,导致不能很好地兼容更多的字符集和其他语言。
  • GBK

    • GBK 是对 GB2312 的扩展编码,采用 2 字节表示汉字,并对原有的字符编码表进行扩展以兼容更多的字符,如繁体中文、日文等。GBK 包含了 GB2312 的全部字符,同时还加入了超过 20,000 个新增字符,但仍然只能用于兼容 GB2312 的中文环境中,不具备国际化的能力。
  • UTF-8

    • UTF-8 是一种 Unicode 编码方式,以兼容 ASCII 为基础来表示 Unicode 字符编码,采用变长字节表示,其中 ASCII 码对应单字节编码,一个汉字则由 3 个字节表示(部分汉字需要 4 个字节),能够表示全球范围内的所有字符,是目前最为广泛使用的字符编码表。UTF-8 具有广泛的应用,可用于 Web 应用、邮件传输、数据库存储等场景。
  • 以上是常见的字符编码表,每种编码表均有其特点和使用场景,开发者需要依据实际的应用需求选择合适的编码表。

3.字符编码相关实际应用有哪些

  • 字符编码是计算机中非常重要的概念,其相关应用也非常广泛,以下列举几个常见的实际应用:

    • 文本编辑和处理

      • 编写文本文档、邮件、代码等,都需要使用字符编码,以确保文本的正确存储、编辑和传输。
    • 网络通信

      • 字符编码在网络通信中也十分重要,包括 HTTP 协议、HTML 网页、API 接口、Web 服务等。例如,在 Web 应用程序中,多数情况下需要使用 UTF-8 编码格式来确保兼容各种语言。
    • 数据存储

      • 在将数据存储到数据库、文件系统、缓存等存储介质时,需要使用适当的字符编码来确保数据的正确存储。
    • 文件传输

      • 文件传输的时候,往往需要使用特定的字符编码格式,使得数据能够在不同操作系统和应用程序之间进行交换。
      • 例如,在 Windows 和 Mac OS X 操作系统中,文本文件的编码方式不同,通过使用良好的字符编码方式,可以避免文字乱码和数据丢失。
    • 区分不同的语言

      • 字符编码也可用于区分不同的语言,根据其使用的字符集和编码方式不同,可以区分中文、英文、日语、韩语等不同的语言,帮助计算机判断并正确显示文本内容。
  • 总之,字符编码在计算机中有着广泛的应用,其正确使用和理解对于不同的应用场景非常重要,以上列举的应用只是常见的几个,实际应用还有很多很多。

day11

1.文件读写模式有哪些,分别有何特点

  • 文件读写模式常用的有以下几种:

  • 读取模式(’r’):

    • 文件以只读方式打开,指针会放在文件开头,如果文件不存在会发生异常。
    • 适用于读取文件内容的操作。
  • 写入模式(’w’):

    • 文件以写入方式打开,指针会放在文件开头,如果文件不存在会创建文件。
    • 用于清空原文件内容并重写文件。
  • 追加模式(’a’):

    • 文件以写入方式打开,指针会放在文件结尾,如果文件不存在会创建文件。
    • 用于在原文件内容结尾追加新内容。
  • 二进制文件读取模式(’rb’):

    • 文件以二进制读取方式打开,指针会放在文件开头,适用于二进制文件(如图片、视频)的读取。
  • 二进制文件写入模式(’wb’):

    • 文件以二进制写入方式打开,指针会放在文件开头,适用于二进制文件的写入。
  • 二进制文件追加模式(’ab’):

    • 文件以二进制写入方式打开,指针会放在文件结尾,
    • 适用于二进制文件的追加。\n\n需要注意的是,在文件操作完成后必须使用close()函数关闭文件,以释放系统资源,避免文件句柄泄露。
  • 此外,Python中也提供了with语句,使用结束自动关闭文件句柄,可以简化代码实现。

2.文件常用操作方法有哪些,各自特征

  • 文件操作方法是指使用Python内置的函数、方法或模块对文件的读取、写入、修改等操作。
  • 常用的文件操作方法有:
  • open():
    • 打开文件。使用文件路径、打开模式等参数打开文件,返回文件句柄。
    • 可以使用with语句代替close()方法。
  • read():
    • 读取文件。读取整个文件或指定字符个数,返回文件内容。
    • 对于大文件不建议使用此方法,可使用readline()或readlines()分行读取。
  • readline():
    • 逐行读取文件。
    • 返回文件中的每一行内容。
    • 通常可以在while循环中使用,用于读取大文件。
  • readlines():
    • 读取整个文件,将每行作为列表中的一个元素。
    • 通常用于读取配置文件等。
  • write():
    • 写入文件。向文件中写入指定字符或字符串。
    • 对于多行文本,可以在每行末尾添加换行符。
  • writelines():
    • 将多行文本写入文件。
    • 接收一个字符串列表作为参数,将列表中的每个字符串写入文件。
  • close():
    • 关闭文件。
    • 使用完成文件操作后,需要使用此方法关闭文件句柄释放系统资源。
  • 需要注意的是,使用文件操作方法时需要遵循Python文件操作的基本规范,注意文件的打开、读取、写入、关闭顺序。同时要注意文件编码的问题,以防止读取或写入出现乱码。

3.简述多用户注册,登录功能思路

  • 实现多用户注册,登录功能的一般思路如下:

  • 注册功能:

    • 创建一个用户注册页面,包含用户名、密码、邮箱等用户信息的输入框;
    • 接收前端传来的用户信息,并进行格式校验,比如检查用户名是否重复、密码是否符合要求等;
    • 将新用户信息存储到数据库中,建议使用哈希加密保护用户密码;
    • 返回注册成功的信息给前端。
  • 登录功能:

    • 创建一个用户登录页面,包含用户名、密码输入框和登录按钮;
    • 接收前端传来的登录信息,并查询数据库中是否存在该用户信息;
    • 若存在,则校验用户输入的密码是否与数据库中存储的相同;
    • 若校验通过,则返回登录成功的信息给前端,同时设置用户 session 保存登录状态;
    • 反之,返回登录失败的信息给前端。
  • 在实现多用户注册、登录功能前,建议了解与相关技术,如html、CSS、JavaScript、Python、MySQL数据库等技术。

  • 可以使用 django、flask等web框架,结合模板引擎、ORM等技术实现快速开发,从而实现多用户注册、登录等功能。

day12

1.文件操作模式有几种,各自有何特点

  • Python中的文件操作模式共有6种,常常在open()函数中使用,各自的特点如下:

  • 'r’模式:

    • 只读模式。
    • 打开一个已经存在的文件用于读取。
    • 如果文件不存在,则会引发FileNotFoundError异常。
  • 'w’模式:

    • 写入模式。打开一个文件用于写入。
    • 如果文件已经存在,则会覆盖原有文件中的数据
    • 如果文件不存在,则会创建一个新的文件。
  • 'x’模式:

    • 独占创建模式。
    • 用于创建一个新文件
    • 如果文件已经存在则会引发FileExistsError异常。
  • 'a’模式:

    • 追加写入模式。
    • 打开一个文件用于追加写入
    • 如果文件不存在则创建一个新文件。
  • 'b’模式:

    • 二进制模式。
    • 与上述模式搭配使用
    • 例如’rb’表示以只读二进制模式打开一个文件。
  • '+’模式:

    • 读写模式,即同时对文件进行读取和写入操作,与上述模式搭配使用
    • 例如’w+’表示以写入模式打开文件并允许读取文件内容。
  • 综上,不同的模式适用于不同的场景,在使用时需要根据需要合理选择。

2.如何控制文件内光标的移动,有几种模式各自有何特点

  • 在Python中,可以使用seek()函数控制文件内光标的移动。
    • seek(offset[, whence])函数用于将文件指针移动到不同的位置(即光标位置)。
    • 函数参数中有两个参数。
      • offset是整数型,表示要移动的字节数(字节是文件操作中的基本单位),如果移动到文件末尾,则offset必须为负数。
      • whence参数可选,表示要移动的起始位置。默认值为0(从文件开头开始),1表示从当前位置开始,2表示从文件末尾开始。
  • 常用的文件模式有三种,各自特点如下:
    • 读模式(’r’):
      • 只能移动光标到文件的开头,因为文件在打开时默认从头开始读取,故而以Read模式打开的文件只允许光标向文件头移动,即whence参数只能为0。
    • 写模式(’w’):
      • 与读模式不同,写模式打开的文件有两种移动光标的方式:通过whence为0或1移动到文件的开头或者当前的文件指针位置。
    • 读写模式(’r+’ 或 'w+’):
      • 既可以在文件中读取数据,也可以写入数据,其中whence参数从文件头为0开始,也可以是1或2。
      • 相较于写模式,它需要用到一个有意思的函数truncate()来控制光标的移动。
      • truncate()函数是用于从文件末尾截取一定长度的数据,以此控制光标的移动。

3.说说你知道的修改文件的思路

  • 修改文件的思路可以分为以下几个步骤:

    • 打开文件:
      • 使用Python内置的open()函数打开要修改的文件,指定相应的文件模式
      • 例如’w’、’a’等。可以使用with语句处理文件,不需要手动调用close()函数。
    • 读取文件内容:
      • 使用read()或者readlines()函数读取文件中的内容。
      • 如果需要修改文件中的某些内容,则需要找到需要修改的内容。
    • 修改文件内容:
      • 可以使用字符串的replace()函数或者正则表达式re模块中的函数进行替换、删除、插入等操作,最终得到修改后的内容。
    • 将修改后的内容写回文件:
      • 使用write()函数将修改后的内容写回到文件中。
    • 关闭文件:
      • 使用close()函数关闭文件。
  • 需要注意的是,在修改文件之前一定要备份原文件(例如使用shutil模块中的copy()函数),以防修改失误导致原文件内容丢失。

  • 同时,在写入修改后的内容时需要小心,避免覆盖文件中的其他内容或者写入不必要的空白字符。

  • 同时在修改文件的同时,也需要考虑文件编码的问题,确保不会出现乱码。

4.什么是函数及函数完整语法结构

  • 函数是一组预定义好的语句块,用于完成特定的功能,并且可以被多次调用。函数通常有输入参数和输出结果。
  • 函数完整语法结构如下:
def function_name(parameters):
    """函数说明文档""" 
    statement(s)
    return [expression]
  • def:Python中定义函数的保留字。
  • function_name:自定义的函数名,遵循标识符命名规则,以字母或下划线开头,后面可以跟字母、数字、下划线等,不能是Python中的保留字。
  • parameters:参数列表,用于接收传入的参数,可以为空。多个参数之间以逗号分隔,参数可以有默认值。
  • """函数说明文档""":可选的函数文档字符串,主要用于函数说明、函数使用文档等,也可通过help()函数查看函数的说明文档。
  • statement(s):函数体,包含一组可执行的语句和操作,完成特定的功能。
  • return [expression]:可选的返回值列表,用于返回函数执行结果。若无返回值,则可省略return语句;若有返回值,则需要使用return关键字返回结果。
  • 例如,定义一个计算两个数之和的函数可以写成以下代码:
def add(a, b):
    """计算两个数之和""" 
    return a + b

day13

1.函数参数的两大分类及两者关系

  • Python中的函数参数可以分为两大类:
    • 位置参数和关键字参数(也称为命名参数)。
    • 其中,位置参数是指在函数调用中按顺序传递给函数的参数,而关键字参数是指使用参数名和值对的形式进行传递的参数,可以不按照顺序传递参数。
  • 这两者之间的关系是:
    • 在函数调用中,必须首先传递位置参数,然后才能传递关键字参数。
    • 具体来说,如果一个函数同时接受位置参数和关键字参数,那么在调用该函数时,首先要按照位置顺序传递所有位置参数,然后可以使用关键字参数来传递其余的参数。
  • 以下是一个示例函数,同时接受位置参数和关键字参数:
def my_function(a, b, c=0, d=0):
    print("a =", a)
    print("b =", b)
    print("c =", c)
    print("d =", d)

my_function(1, 2)
my_function(1, 2, c=3)
my_function(1, d=4, b=2)
  • 在上面的代码中,my_function()函数有两个位置参数和两个关键字(命名)参数。在第一次函数调用中,我们只传递了两个位置参数。在第二次调用中,我们传递了三个参数,其中第三个参数使用了关键字方式进行传递。在第三次调用中,我们使用了两个关键字参数来指定传递的参数。
  • 总之,位置参数和关键字参数是Python中函数参数的两大分类,但它们之间是互相依存的关系。
    • 位置参数必须先传递,并且任何剩余的参数可以使用关键字参数以混合的方式传递,可以最大程度地提高程序的可读性和可维护性。

2.阐述函数参数的各小类及各自特征

  • Python中的函数参数可以分为以下几个小类:

    • 位置参数(Positional arguments)

      • 位置参数是在函数调用时根据函数定义的顺序进行传递的参数。
      • 该类参数没有默认值,如果在函数调用中省略了对应的位置参数,会引发TypeError错误。位置参数的特征是:
        • 必须在函数定义中声明
        • 形式如x, y, z,按照位置顺序传递
        • 必须按照函数定义中的参数顺序进行传递
    • 默认参数(Default arguments)

      • 默认参数在函数定义中已经为其参数指定了一个默认值。
      • 如果在函数调用时未提供对应的参数,则使用默认值。默认参数的特征是:
        • 函数定义中声明,指定一个默认值
        • 可以在函数调用时省略
        • 通常设置为已知或常见的值,以防缺少参数
    • 关键字参数(Keyword arguments)

      • 关键字参数可以通过指定参数名来传递给函数。
      • 关键字参数通常用于可选参数的情况下,或者在涉及多个参数的函数中,以减少歧义。关键字参数特征是:
        • 按照参数名传递
        • 具有可读性和可维护性
        • 可以在任何顺序中传递参数
        • 没有输入参数时会使用默认值
    • 可变位置参数(Variable Positional arguments)

      • 可变位置参数是一种特殊类型的参数,可以在函数调用时传递可变数量的位置参数。
      • 可变位置参数通常使用星号(*)来表示。可变位置参数的特征是:
        • 在函数定义时使用*args表示
        • 可以传递额外的位置参数
        • 所有额外的位置参数都会被收集到元组中
    • 可变关键字参数(Variable Keyword arguments)

      • 可变关键字参数是一种特殊类型的参数,可以在函数调用时传递可变数量的关键字参数。
      • 可变关键字参数通常使用两个星号(**)来表示。可变关键字参数的特征是:
        • 在函数定义时使用**kwargs表示
        • 可以传递额外的关键字参数
        • 所有额外的关键字参数都会被收集到字典中
  • 总之,Python中的函数参数分为位置参数、默认参数、关键字参数、可变位置参数和可变关键字参数五种小类,每种参数都有自己的特征和用途,有效地使用不同类型的参数可以提高代码的可读性和可维护性。

3.什么是名称空间,有哪些分类,查找顺序如何确定

  • Python中的名称空间(Namespace)

    • 指的是变量或函数名与特定对象之间的映射关系。
  • Python中名称空间的主要作用

    • 是避免同名对象之间的冲突,通过确保每个名称只与一个对象绑定来确保代码中的正确性。
  • Python中的名称空间可以分为以下几种分类:

    • 内置名称空间(Built-in Namespace)

      • 内置名称空间中包含了Python解释器中默认存在或由标准库提供的函数、模块、变量等对象

        • 例如len()、print()、int、float等。
        • 这些名称可以在Python代码中直接访问,无需进行导入或定义。
      • 全局名称空间(Global Namespace)

        • 全局名称空间中包含当前模块中定义的全局变量、函数、类等对象。
        • 全局名称空间在模块被导入时创建,在模块结束时销毁。
      • 本地名称空间(Local Namespace)

        • 本地名称空间指的是函数、方法或类定义的名称空间,在函数调用时创建,在函数结束时销毁。
        • 本地名称空间包含了函数的参数、局部变量和变量定义的参数。
      • 查找顺序如何确定:Python在查找名称空间时按照以下顺序进行查找:

        • 查找本地名称空间

        • 如果名称未在本地名称空间中找到,则查找全局名称空间

        • 如果名称在全局名称空间中也没有找到,则查找内置名称空间

  • 如果一个名称在多个名称空间中都有定义,则使用规定的查找顺序,使用最先找到的对象。

    • 如果在任何名称空间中都找不到该名称,则引发NameError错误。

day14

1.什么是装饰器,涉及到哪些知识,

装饰器(Decorator)是Python语言中的一种高级特性,它可以在不修改源代码的情况下,通过在现有代码周围添加包装的方式,扩展或修改函数、类或方法的行为。具体来说,装饰器是至少一个函数,它接受并返回其他函数,并在调用它返回的函数时执行一些额外操作。装饰器通常用于实现横切关注点(cross-cutting concerns)的代码,如日志记录、性能测量、验证等。
涉及到的知识包括函数、闭包、装饰器语法等。在Python中,函数是一等公民(first-class objects),意味着它们可以作为参数传递、赋值给其他变量、存储在容器中以及从函数中返回。这为编写装饰器提供了一个有利的基础。另外,Python中还有嵌套函数(nested functions)和闭包(closure)的概念,允许我们实现在一个函数内定义另一个函数。
  • 装饰器的实现方式和语法也需要注意。
  • 通常,装饰器是一个带有一个函数作为其唯一参数的函数,返回一个包装函数(wrapper function)的函数。
  • 要将装饰器应用于函数或类,只需使用@符号加上装饰器函数的名称,将其放在定义该函数或类的行之前。
  • 装饰器的执行过程可以参考以下示例:
@decorator
def func():
    pass
    
# 等价于

def func():
    pass
    
func = decorator(func)
  • 值得注意的是,装饰器也可以接受参数,以便在使用时为其提供自定义选项。
  • 这需要再次嵌套两个函数,其中外部函数接受装饰器参数,并返回一个接受包装函数的内部装饰器函数。
  • 装饰器语法和实现方式可能有些不同,但它们都能够提供简洁、简单和优雅的方案,以扩展或修改Python中存在的任何函数或类的行为。

2.默写出装饰器通用模板

def my_decorator(func):
    def wrapper(*args, **kwargs):
        # 这里添加装饰器要执行的代码
        result = func(*args, **kwargs)
        # 这里添加装饰器要执行的代码
        return result
    return wrapper
  • 该模板定义了一个包装器函数wrapper
    • 它将接受任何数量和类型的位置和关键字参数。
  • wrapper函数执行前后可以执行包装器要执行的额外代码,并返回原函数的结果。
  • 在应用装饰器时,只需将原函数作为参数传递给装饰器,并使用@符号来应用装饰器即可:
@my_decorator
def my_function():
    pass
  • 在这个示例中,my_function()函数将被包装在my_decorator()函数中,并在调用该函数时运行额外的代码。

3.什么是装饰器语法糖,有何执行特征

装饰器语法糖是Python中用于应用装饰器的一种简写,它使用@符号将装饰器函数应用于另一个函数或方法,使代码更加简洁和易读。

装饰器语法糖的执行特征是,在定义函数或方法时在其上方添加@符号和装饰器名称,然后将该函数作为参数传递给装饰器函数,然后由装饰器函数返回修改过的原始函数。这样就可以将功能添加到原始函数或方法而不修改原始函数或方法代码。

它的主要优点是可以在不修改原始函数的代码或深入理解它的工作原理的情况下,轻松实现功能扩展。以下是一个示例装饰器函数和代码:
def my_decorator(func):
    def wrapper(*args, **kwargs):
        #这里添加装饰器要执行的代码
        func(*args, **kwargs)
        #这里添加装饰器要执行的代码
    return wrapper

@my_decorator
def my_function():
    pass
  • 在这个示例中,我们首先定义了一个my_decorator()函数,它使用一个名为wrapper()的内部包装器函数将它作为参数传递的函数包装起来。
  • 然后,我们使用装饰器语法糖将my_decorator()函数应用于my_function()函数,并且在执行my_function()函数时会执行my_decorator()函数定义的增强功能。
  • 即在my_function()函数执行前后添加一些额外的操作。

day15

1.什么是递归函数,python默认最大递归深度是多少,递归函数正常执行的前提条件是什么

# 什么是递归函数
## 是指在函数的定义中使用函数自身的方法。
# python默认最大递归深度是多少
# 1000
# 递归函数正常执行的前提条件是什么
## 1.递归就是在过程或函数里调用自身
## 2.必须有一个明确的递归结束条件,称为递归出口。

2.什么是算法,能详细说说二分法前提条件及主要思路吗

# 什么是算法
## 为解决一个问题而采取的方法和步骤,就称为“算法”
# 二分法前提条件
##  数组为有序数组,同时数组中无重复元素
# 二分法主要思路
## 通过取middle的方式,缩小[l, r]区间定位target值
## 分开找开始位置和结束位置,即对第一个等于target和最后一个等于target的下标位置进行二分查找。

day16

1.列举你所知道的各种生成式

列表生成式:用于创建新的列表,语法形式为[expression for item in iterable]。

字典生成式:用于创建新的字典,语法形式为{key_expression: value_expression for item in iterable}。

集合生成式:用于创建新的集合,语法形式为{expression for item in iterable}。

生成器表达式:与列表生成式类似,但它返回一个生成器对象,语法形式为(expression for item in iterable)。

元组生成式(Python 中没有):由于元组是不可变类型,因此没有元组生成式的概念。

2.什么是匿名函数,如何使用

# 什么是匿名函数?
匿名函数是没有名称的函数,通常用于临时或简单的操作,可以直接定义和使用而不需要事先声明。
# 如何使用?
# 在Python中,使用lambda关键字可以创建匿名函数。
square = lambda x: x**2
# 这个函数可以像普通函数一样调用:
result = square(5)
print(result)  # 输出 25
# 也可以将匿名函数作为参数传递给其他函数,例如:
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares)  # 输出 [1, 4, 9, 16, 25]
# 上面的代码中,map函数接受一个函数和一个可迭代对象作为参数,并返回一个新的可迭代对象,其中包含对原始对象应用函数后得到的结果。在这里,我们使用了一个匿名函数来计算每个数字的平方值。

3.常用内置函数及各自主要功能

print():将对象打印到控制台。
len():返回对象的长度,例如字符串、列表、元组等。
input():接受用户输入并返回一个字符串。
type():返回对象的数据类型。
int():将一个字符串或浮点数转换为整数。
float():将一个字符串或整数转换为浮点数。
str():将其他数据类型转换为字符串。
list():将一个可迭代对象转换为列表。
tuple():将一个可迭代对象转换为元组。
range():生成一个包含指定范围内整数的序列。
max():返回给定参数的最大值。
min():返回给定参数的最小值。
sum():返回一个可迭代对象中所有元素的和。
sorted():对可迭代对象进行排序。
zip():将多个可迭代对象打包成一个元组构成的列表。

day17

1.常用内置函数及各自主要功能

print():将指定的值打印到控制台或文件中。

input():允许用户在控制台中输入值并返回其输入。

len():返回对象的长度或元素数量。

type():返回对象的类型。

str():将其他类型的对象转换为字符串。

int():将其他类型的对象转换为整数。

float():将其他类型的对象转换为浮点数。

list():将其他类型的对象转换为列表。

tuple():将其他类型的对象转换为元组。

dict():返回一个新的字典或将一个可迭代对象转换为字典。

range():返回一个指定范围内的数字序列。

sum():返回指定序列的总和。

sorted():排序给定的序列并返回其副本。

zip():将两个或更多序列依次配对,并返回用于迭代的元组序列。

map():将一个函数应用于序列的每个元素,并返回一个包含结果的列表。

filter():接受一个函数和一个序列,返回一个包含序列中所有返回True的元素的列表。

open():打开文件并返回一个文件对象。

abs():返回指定数字的绝对值。

2.什么是可迭代对象,迭代器对象,两者有何关系

可迭代对象是指可以被迭代的对象,如列表、元组、字典、集合、字符串等。
简单来说,如果一个对象可以用于for循环中,那么它就是可迭代对象。可迭代对象可以使用内置函数iter()创建一个迭代器对象。

迭代器对象是指一个带有特殊方法__next__()的可迭代对象,该方法将按顺序返回可迭代对象中的每个元素。当到达可迭代对象中的最后一个元素时,__next__()方法会引发一个StopIteration异常。

迭代器对象维护并跟踪序列中的迭代位置,并且与可迭代对象不同,它不会在内存中存储整个序列。这使得迭代器对象非常适合处理大型序列,因为它只需在需要访问下一个元素时才将其加载到内存中。

可迭代对象与迭代器对象之间有一定的关系,可以通过内置函数iter()将可迭代对象转换为迭代器对象。
每次调用迭代器对象的__next__()方法时,它将返回可迭代对象的下一个元素,直到到达可迭代对象的结尾。
如果再尝试访问已经到达结尾的迭代器对象,则会引发一个StopIteration异常。

总结起来,一个可迭代对象是一个包含有序元素的对象,而迭代器对象是一个特殊的可迭代对象,它通过跟踪迭代位置来提供更高效的访问方法。
可以通过iter()函数将一个可迭代对象转换为一个迭代器对象,从而实现对可迭代对象中元素的遍历。

3.for循环内部本质是什么

for循环是一种迭代方法,用于遍历指定序列中的每个元素,将每个元素赋值给循环变量,然后在每次循环中执行代码块。
for循环的本质是迭代器,它会通过调用可迭代对象的__iter__()方法创建一个迭代器对象,并反复调用迭代器对象的__next__()方法来遍历序列。
for循环过程中,首先使用__iter__()方法创建迭代器对象,然后向该迭代器对象请求下一个值。
每次迭代都会调用迭代器对象的__next__()方法,直到迭代器引发一个StopIteration异常,表明已经到达序列的末尾。
而在Python内部,for循环只是迭代器的语法糖,它隐藏了许多底层细节,使代码更加简单和易读。

4.什么是异常,主要分为几个部分,有哪些类型,代码中如何使用

异常(Exceptions)是指在程序执行期间出现错误或异常情况时,Python解释器会引发异常对象,以便用户能够识别该错误或异常情况,并采取相应的措施来处理它。
异常主要分为三个部分:异常的类型、异常的值和追溯信息。其中,异常的类型指明了引发异常的问题类型,异常的值是一个对象,用于描述错误的详细信息,而追溯信息是指异常的上下文信息,包括引发异常的代码行等。
Python内置有多种异常类型,包括但不限于:

NameError:尝试访问未定义的变量。

TypeError:内置操作或函数应用于不适当类型的对象时引发。

ValueError:传递给一个函数的参数不是该函数所期望的类型或值时引发。

ZeroDivisionError:除数为0时引发。

FileNotFoundError:尝试打开不存在的文件时引发。

在Python代码中,可以使用try/except语句来处理异常。try语句用于包含可能引发异常的代码块,而except语句则会捕获并处理任何引发的异常。以下是一个简单的示例:

try:
    num = int(input("请输入一个数字:"))
    print("你输入的数字是:", num)
except ValueError as e:
    print("出错了!", e)
  • 在上面的代码中,我们尝试将输入的数据转换为整数。
    • 如果操作成功,我们就会打印此数字;
    • 否则,我们就会抛出一个ValueError异常,并打印适当的错误消息。
  • except语句中,我们使用了as关键字来将异常对象指定为变量e,以便我们在处理错误时可以更方便地访问该异常对象的属性。这是在实际开发中非常有用的技巧。

day18

1.手写for循环本质代码

  • for循环的本质代码其实是一个while循环,可以用以下代码表示:
for i in sequence:
    # 代码块
  • 等同于:
iterator = iter(sequence) # 获取序列的迭代器
while True:
    try:
        i = next(iterator) # 获取下一个元素
    except StopIteration: # 如果取到了最后一个元素,结束循环
        break
    # 代码块
  • 在迭代器上调用next()方法,可以逐一返回序列中的元素
    • 当序列中没有元素时,调用next()方法将会引发StopIteration异常,从而结束循环。
  • 因此,使用for循环可以使代码更简洁易懂,避免了手动处理循环中的迭代器和异常处理。

2.什么是生成器,生成器和迭代器有何区别,生成器表达式有何特征

  • 生成器是一种特殊的迭代器,可以通过函数来创建。

    • 与列表等数据结构不同,生成器不会一次性将所有元素加载到内存,而是按需生成每个元素。
  • 生成器与迭代器的区别在于

    • 迭代器是一种不断向前访问序列或集合的对象
    • 而生成器是一种用于生成一个元素序列的函数,可以随时暂停并在需要时继续执行。
    • 换句话说,迭代器需要显式体现下一个值,而生成器则会隐式地返回下一个值。
  • 生成器表达式是一种生成器的快速语法,使用圆括号括起来的表达式,用于生成一个元素序列。

    • 生成器表达式与列表解析类似,但只生成一个值,然后等待下一个值的计算,而不是一次性生成整个序列。
  • 其特点包括

    • 节省内存,延迟计算,具有类似于迭代器的能力以及代码简洁易读。

3.列举至少十个常见内置函数名称及功能

print():将一个或多个值输出到控制台。
len():返回序列(例如字符串、列表和元组)或字典中元素的数量。
sorted():对可迭代对象进行排序,并返回一个新的排序后的列表。
max()/min():返回序列中最大/最小的元素。
range():生成一个整数序列。
type():返回给定对象的数据类型。
str()/int()/float():将给定对象转换为字符串/整数/浮点数类型。
input():从用户那里接收输入。
abs():返回一个数的绝对值。
bool():将其他数据类型转换为布尔类型。

day19

1.什么是模块,如何导入模块

  • 在 Python 中,模块是指一个包含 Python 定义和语句的文件。

    • 模块可以包含函数、类、变量和其他可执行代码,这些代码可以被其他 Python 程序重用。
    • 在 Python 中,每个文件都被称为一个模块,因此,写好的函数、变量可以封装在一个模块中,供其他程序使用。
  • 在 Python 中导入模块可以使用 import 语句。

    • import 语句可以在当前 Python 程序的代码中引入其他模块中的对象(如函数、类、变量)。
  • Python 中的一个模块是一个文件,因此导入模块需要指定模块的名称(不带扩展名)。

  • 常见的导入方式有以下几种:

    • 直接导入模块:
      • import module_name
    • 导入模块中的某个函数或变量:
      • from module_name import function_name, variable_name
    • 给模块起一个别名,方便在程序中使用:
      • import module_name as alias_name
  • 例如,如果有一个 my_module.py 文件包含了一些函数和变量,那么我们可以使用下面的导入方式:

import my_module

result = my_module.my_function()
  • 或者使用以下方式导入指定函数:
from my_module import my_function

result = my_function()
  • 我们可以使用别名来导入模块,如下所示:
import my_module as mm

result = mm.my_function()

需要注意的是,要执行导入的模块中的代码,需要运行该模块(而不是仅仅导入)。

因此,在导入模块之后,需要调用该模块中的函数、变量或类来运行列在其中的代码。

2.针对模块的导入有哪些小技巧

  • 一次导入多个模块

    • 在一个 import 语句中可以同时导入多个模块,这有助于简化代码。例如,import module1, module2, module3

    • 使用 from … import * 导入模块

  • 如果需要导入模块中的所有函数和变量,可以使用 from module_name import * 的方式。但是这种方式不被推荐,因为它可能导致一些命名冲突,而且不明确导入了哪些函数和变量。

  • 将模块作为可执行文件使用

    • 在 Python 中,模块可以被作为脚本文件执行。因此,我们可以在模块中定义一些可执行代码,并将其作为可执行文件来运行。
    • 例如,我们在模块中定义了一个函数,可以在脚本文件中直接运行该函数。
  • 将模块作为包使用

    • Python 中的包是指一个文件夹包含了多个模块。
    • 在文件夹中包含一个 init.py 文件可以将文件夹转换为包。
    • 使用包可以更好地组织模块并避免命名冲突。
  • 使用 importlib.reload(module_name) 重新加载模块

    • 当我们在脚本中调用某个模块时,Python 会将该模块加载到内存中,并在后续访问中重复使用该模块。
    • 如果修改了模块中的代码,并想要重新加载,可以使用 importlib.reload 函数重新加载该模块。
  • 使用 as 别名

    • 在导入模块时可以使用 as 关键字给模块设置别名,可以方便代码阅读和模块的重命名。
    • import module_name as module_alias_name
  • 总的来说,对于模块导入,建议在程序中多使用模块别名这种方式,这会使代码更加易读、易于调试并易于维护。

3.模块的查找顺序是什么,如何做到导入模块不会轻易报错

  • 在 Python 中,当你使用 import 语句时,Python 解释器会按照一定的顺序在指定的路径下搜索模块。
  • 搜索的顺序如下:
    • 当前目录
    • 环境变量 PYTHONPATH 中列出的每个目录
    • Python 默认安装路径中对应的目录
  • 如果在这些地方都没有找到该模块,Python 解释器将抛出 ModuleNotFoundError 异常来提示用户。
    • 如果有多个模块导入了同一模块,或者在相同的代码库中有多个 Python 文件,为了避免出现命名冲突或其他错误,我们需要掌握一些技巧,以确保导入模块时不会轻易出错。
  • 以下是一些实践技巧,可以帮助你避免模块导入时出错:
    • 创建一个虚拟环境

      • 通过创建一个虚拟环境,将项目与其依赖项隔离开来,可以避免导入新模块时出现依赖问题。
    • 确保路径正确

      • 在导入模块时,一定要指定正确的路径和模块名称。建议使用绝对路径或相对路径导入模块,并避免使用硬编码。
    • 使用相对导入

      • 相对导入是指从当前模块所在的位置开始,使用相对路径导入另一个模块。相对导入使用 . 和 … 表示当前目录和父目录。
    • 避免使用 from module import *

      • 尽管 from module import * 很方便,但它会导致命名冲突和可读性降低。因此,建议避免使用这种方式,并使用显式导入。
    • 添加 init.py 文件

      • 如果你希望模块所处的文件夾被视为一个包,需要添加一个名为 init.py 的空文件。这样,当你导入模块时,Python 解释器会将文件夹视为包。
  • 总之,一定要在编写代码时格外小心,留意编写的模块与当前模块以及 Python 内置模块之间的名称冲突问题,以及确保找到适当的文件路径,以尽可能避免出现导入模块时出错。

day20

1.写出软件开发目录规范,每个文件夹的名称和功能

软件开发目录规范可以按照不同需求而定,这里提供一种常用的目录结构作为参考:

├── bin                    # 存放可执行文件 
├── build                  # 存放编译输出文件 
├── docs                   # 存放文档
│   ├── api                # 存放 API 文档
│   ├── manual             # 存放用户手册、安装/配置说明等
│   └── release_notes      # 存放版本发布说明
├── src                    # 存放源代码
│   ├── lib                # 存放库文件
│   ├── module             # 存放系统模块
│   └── main.cpp           # 主程序入口文件
├── test                   # 存放单元测试文件
├── tools                  # 存放开发用的工具
├── vendor                 # 存放第三方依赖库或插件
├── LICENSE                # 存放软件许可证
├── README.md              # 存放项目介绍
└── TODO.md                # 存放未来工作计划

各文件夹的功能如下:

  • bin:
    • 存放可执行文件,例如编译后生成的可执行文件、命令行工具等。
  • build:
    • 存放编译器生成的中间文件和输出文件,例如目标文件、库文件、可执行文件等。
  • docs:
    • 存放项目文档,包括 API 文档、用户手册、安装/配置说明、版本发布说明等。
  • src:
    • 存放源代码文件,包括库文件和系统模块,主程序入口文件等。
  • test:
    • 存放测试用例文件,用于单元测试和功能测试。
  • tools:
    • 存放开发用的工具,例如脚本、编译器、代码生成工具等。
  • vendor:
    • 存放第三方依赖库或插件,例如引用的外部库和框架组件。
  • LICENSE:
    • 存放软件许可证,说明本软件的使用、修改和分发条件。
  • README.md:
    • 存放项目介绍,包括项目简介、安装说明、使用说明等。
  • TODO.md:
    • 存放未来工作计划,即将要完成和实现的功能。

2.利用软件开发目录规范写出ATM的模板

ATM(Automated Teller Machine,自动取款机)的项目目录结构可以如下所示:

├── bin                    # 存放可执行文件
├── build                  # 存放编译输出文件
├── docs                   # 存放文档
│   ├── api                # 存放 API 文档
│   ├── manual             # 存放用户手册、安装/配置说明等
│   └── release_notes      # 存放版本发布说明
├── src                    # 存放源代码
│   ├── lib                # 存放库文件
│   ├── modules            # 存放系统模块,例如 withdrawal、deposit、balance_inquiry 等
│   └── main.cpp           # 主程序入口文件
├── test                   # 存放单元测试文件
├── tools                  # 存放开发用的工具
├── vendor                 # 存放第三方依赖库或插件
├── LICENSE                # 存放软件许可证
├── README.md              # 存放项目介绍
└── TODO.md                # 存放未来工作计划

各文件夹的功能如下:

bin: 存放可执行文件,包括编译后生成的可执行文件,方便用户使用 ATM 自动取款机。
build: 存放编译器生成的中间文件和输出文件,例如目标文件、库文件、可执行文件等。
docs: 存放项目文档,包括 API 文档、用户手册、安装/配置说明、版本发布说明等,方便用户了解 ATM 工作原理、使用方法。
src: 存放 ATM 系统源代码,包括库文件和系统模块,主程序入口文件等。
test: 存放测试用例文件,用于单元测试和功能测试,测试 ATM 系统功能是否正常、稳定。
tools: 存放开发用的工具,例如脚本、编译器、代码生成工具等,方便开发人员对 ATM 系统进行调试和优化。
vendor: 存放第三方依赖库或插件,例如引用的外部库和框架组件,方便 ATM 系统开发和运行。
LICENSE: 存放软件许可证,说明本软件的使用、修改和分发条件,遵守相关法规和标准。
README.md: 存放项目介绍,包括 ATM 自动取款机的功能、使用方法、系统特点和注意事项等。
TODO.md: 存放未来工作计划,即将要完成和实现的功能,例如添加新的取款/存款方式、优化系统界面等。

day20.1

1.写出软件开发目录规范,每个文件夹的名称和功能

2.利用软件开发目录规范写出ATM的模板


- ATM 项目根目录
    - README.md 项目说明书

- conf 配置文件
    - settings.py

- lib 公共方法文件
    - common.py

- core(用户视图层) 存放用户视图层代码文件
    - src.py

- interface(逻辑接口层) 存放核心业务逻辑代码
    - user_interface.py 用户相关接口
    - bank_interface.py 银行相关接口
    - shop_interface.py 购物相关接口

- db(数据处理层) 存放数据与数据处理层代码
    - db_hander.py 数据处理层代码
    - user_data 用户数据

- log 存放日志文件

- bin(启动文件目录) 存放启动文件的方式一,单独创建目录
    - main.py

day21

1.列举re模块中的方法及各自作用

  • re 模块是 Python 中用于正则表达式处理的标准库,其中包含了多个用于正则表达式处理的方法。
  • 以下是部分 re 模块中常用的方法及其作用:
    • re.compile(pattern, flags=0)
      • 编译正则表达式,返回一个正则表达式对象;
    • re.search(pattern, string, flags=0)
      • 在字符串中搜索正则表达式的第一个匹配项,返回一个 Match 对象;
    • re.match(pattern, string, flags=0)
      • 尝试从字符串的开头开始匹配正则表达式,返回一个 Match 对象;
    • re.findall(pattern, string, flags=0)
      • 搜索字符串中所有与正则表达式匹配的子串,并以列表形式返回所有匹配项;
    • re.sub(pattern, repl, string, count=0, flags=0)
      • 在字符串中用新的字符串替换匹配的子串,返回替换后的新字符串;
    • re.split(pattern, string, maxsplit=0, flags=0)
      • 根据正则表达式匹配项来分割字符串,并将分割后的子串以列表形式返回。
  • 这些方法中,re.compile() 是对正则表达式进行编译的方法,可以将一些常用的正则表达式编译成对象以便多次使用,提升正则表达式的匹配效率。
  • 而其他方法都是根据正则表达式来进行字符串的匹配、查找、替换和分割等操作的方法。

2,写出正则中你所知道的各种特殊符号以及作用,尽可能多的写

  • 正则表达式中,特殊符号表示了一些特殊的含义或者规则。以下是一些常见的正则表达式中的特殊符号及其作用:
.:表示匹配除了换行符以外的任意字符。
^:表示匹配行首,以匹配起始位置。
$:表示匹配行尾,以匹配结束位置。
\d:表示匹配任意数字,相当于 [0-9]。
\D:表示匹配任意非数字字符,相当于 [^0-9]。
\w:表示匹配任意字母数字字符或下划线,相当于 [a-zA-Z0-9_]。
\W:表示匹配任意非字母数字字符或下划线,相当于 [^a-zA-Z0-9_]。
\s:表示匹配任意空白字符,包括空格、制表符、换行符等。
\S:表示匹配任意非空白字符。
*:表示匹配前一个字符或子表达式的零次或多次,相当于 {0,}。
+:表示匹配前一个字符或子表达式的一次或多次,相当于 {1,}。
?:表示匹配前一个字符或子表达式的零次或一次,相当于 {0,1}。
|:表示或操作符,可以在两个或多个表达式之间选择一个匹配的结果。
():表示分组,可以将多个子表达式组合成一个整体,方便后续的引用或操作。
[]:表示字符集,可以匹配括号中的任意一个字符。其中可能包含特殊的字符范围,如 [a-z] 表示匹配所有小写字母。
  • 还有一些常见的特殊符号包括 {} 表示重复次数,*? 和 +? 表示非贪婪匹配,^ 在 [] 中使用表示取反等。以上是一些常见的正则表达式中的特殊符号及其作用,还有其他一些特殊符号在不同的正则实现中可能存在区别。

day22

1.时间的三种表现形式,格式化时间中有哪些常见符号

时间可以有三种表现形式:
1. 时间戳(Timestamp):指某个时间点距离一个固定的起始时间(通常为Unix纪元,即1970年1月1日00:00:00 UTC)的秒数。
2. 标准时间(Standard time):以人类可读的方式表示的日期时间,比如2023年6月16日13点10分29秒。
3. 时间间隔(Time interval):指两个时间点之间的时间长度,可以表示为一段时长,比如5小时30分钟。

常见的格式化时间符号如下所示:
1. %Y:年份,例如2023。
2. %m:月份,范围为01-12。
3. %d:一个月中的第几天,范围为01-31。
4. %H:小时数,24小时制,范围为00-23。
5. %M:分钟数,范围为00-59。
6. %S:秒数,范围为00-59。
7. %w:一周中的第几天,范围为0-6,其中0表示星期天。
8. %x:日期,例如06/16/23。
9. %X:时间,例如13:10:29。

2.如何获取当前时间,列举跟时间相关的方法

在大多数编程语言中,获取当前时间的方法和函数都是类似的,以下是常见的方法和函数:
# 1. 使用系统函数获取当前时间,例如在Python中使用datetime.datetime.now()
# 可以获取当前日期和时间。

# 2. 获取当前的时间戳,在Python中使用
time.time()
# 可以获得当前时间戳。

#3. 使用特定的格式将当前时间格式化为字符串,例如在JavaScript中使用
new Date().toLocaleString()
#可以将当前时间转换为本地格式化的字符串。

#4. 获取当前年、月、日、时、分、秒等单独的部分,例如在Java中使用
Calendar.getInstance().get(Calendar.MONTH)
#就可以获得当前的月份。
#5. 在某些操作系统中,也可以通过系统命令获取相关的时间信息,例如在Linux下使用
date
# 命令可以查看当前日期和时间。

3.写出生成随机验证码的代码

day23

1.os 模块至少写出 5个常用的方法,尽可能多的写

  • os.getcwd()

    • 获取当前工作目录(Current Working Directory,CWD)的路径。
  • os.chdir(path)

    • 改变当前工作目录到指定路径。
  • os.listdir(path='.')

    • 列出指定目录下的所有文件和子目录名。
  • os.mkdir(path, mode=0o777, *, dir_fd=None)

    • 创建一个目录,如果该目录已经存在则抛出异常。
  • os.rmdir(path, *, dir_fd=None)

    • 删除指定目录。该目录必须是空目录,否则会引发OSError异常。
  • os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)

    • 将文件或目录从src更改为dst。
  • os.remove(path, *, dir_fd=None)

    • 删除指定的文件。
  • os.path.join(path1, path2, ...)

    • 将多个路径组合起来,返回一个新路径。如果任何一个路径存在绝对路径,之前的所有路径都将被丢弃,而仅使用绝对路径。
  • os.path.abspath(path)

    • 返回指定路径的绝对路径。
  • os.path.splitext(path)

    • 分离文件名和扩展名,返回一个元组,第一个元素是文件名,第二个元素是扩展名。
  • os.path.exists(path)

    • 检查指定的路径是否存在。
  • os.path.isdir(path)

    • 检查指定的路径是否为目录。
  • os.path.isfile(path)

    • 检查指定的路径是否为文件。
  • os.path.getsize(path)

    • 返回指定路径的文件大小(字节数)。
  • os.environ

    • 获取操作系统的环境变量。

2.什么是json 格式的数据,有何特点,json 模块的几个方法是什么,有什么作用,pickle 模块有什么特点,如何使用

  • JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,可以被人类和机器读取。

    • 它的特点是语法简洁明了,易于理解和编写,并且在各种编程语言和平台之间都有良好的互操作性。
  • JSON模块是Python内置的标准库,主要用于编码和解码JSON数据格式。它提供了四个方法:

    • json.dumps()
      • 将Python对象转换为JSON格式的字符串。
    • json.loads()
      • 将JSON格式字符串转换为Python对象。
    • json.dump()
      • 将Python对象转换为JSON格式的字符串并写入文件。
    • json.load()
      • 从文件中读取JSON格式的字符串并解析为Python对象。
  • 这些方法使得我们能够方便地处理json格式的数据,例如从网络上获取json数据或者将数据存储到本地文件中。

  • pickle模块也是Python内置的标准库,它主要用于序列化和反序列化Python对象

    • 与json不同的是,pickle可以序列化Python的所有对象类型,包括自定义类和函数。
    • pickle 的特点是
      • 数据表现形式是二进制的
      • 并且支持任意复杂的数据类型。
    • 使用pickle的时候,我们需要注意的是它会将对象直接序列化,因此从不受信任的源或者未经身份验证的数据中加载pickle数据是有安全风险的。
  • 我们可以使用以下代码来演示如何使用pickle模块将一个对象进行序列化和反序列化:

import pickle

# 定义一个Python对象
data = {'name': 'Alice', 'age': 25, 'email': 'alice@example.com'}

# 对象序列化为二进制文件
with open('data.pickle', 'wb') as f:
    pickle.dump(data, f)

# 从二进制文件中反序列化得到Python对象
with open('data.pickle', 'rb') as f:
    data_loaded = pickle.load(f)
  • 以上代码中,我们首先定义了一个Python字典对象,并将其写入文件data.pickle中。
    • 然后我们读取这个文件,并将其反序列化为Python对象。

day24

day25