Python基础学习笔记(二)

文章目录

一、程序结构

模块 Module

  1. 定义:包含一系列的数据、函数、类的文件,通常以.py结尾;

  2. 作用:让一些相关的数据,函数,类有逻辑的组织在一起,是逻辑结构更加清晰。利于多人合作开发;

  3. 导入:可以跨模块访问类,本质是创建变量接收其他的模块/模块中的成员。

    1. 方式一:直接导入整个模块,使用模块名/别名调用成员;
      • import 模块名( as 别名)
    2. 方式二:导入部分类、方法或变量到当前作用域中,直接使用导入的成员;
      • from 模块名 import 方法名/变量名( as 别名)
    3. 方式三:导入模块的所有成员,需注意是否与自身成员冲突;
      • from 模块名 import * ( as 别名)
  4. 模块变量:

    • __all__ 变量:定义可导出成员,仅对 from 模块 import * 语句有效;

    • __doc__ 变量:文档字符串,注释;

    • __file__ 变量:模块对应的文件路径名;

    • __name__ 变量:模块自身名字,可以判断是否为主模块;

      • 被导入的模块,打印的是真实的模块名字;

      • 第一次运行的模块,打印的是 __main__ ,是主模块;

        python 复制代码
        # main为程序的入口
        # 如果当前模块是主模块,代码执行,否则不执行
        if __name__ == "__main__":
            print("执行的代码")
  5. 加载过程:

    1. 在模块导入时,模块中的所有语句都会执行。
    2. 如果一个模块已经导入,再次导入时不会重复执行;
  6. 模块分类:

    1. 内置模块:builtins,在解析器的内部可以直接使用;
    2. 标准库模块:安装Python时已安装且可直接使用;
    3. 第三方模块:需要自己安装,通常为开源;
    4. 自定义模块:自己编写的模块,可作为其他人的第三方模块;

包 package

  1. 定义:将模块以文件夹的形式进行分组管理。

  2. 作用:让一些相关组织在一起,使逻辑结构更加清晰。

  3. 导入:

    • 方式一:import 包名.模块名( as 别名)

    • 方式二:from 包名.模块名 import 方法名/变量名( as 别名)

    • 方式三:from 包名.模块名 import * ( as 别名)

      • 注意:如果导入的是一个包,那么需要在包的 __init__.py 模块中设置 __all__ 属性;

        python 复制代码
        __init__.py		# 设置导入的内容
        	__all__ = ["Student"]
        
        from com.it.package import *
        
        Student.fun01()
        Student.Student(23).fun02()
    • __init__.py 的作用:

    1. 包内必须存在的文件,象征当前文件夹是一个包;
    2. 导入的时候会自动调用执行 __init__.py 模块
    • 搜索顺序:内置模块 sys

      • 导入模块成功的唯一条件:
        • sys.path + 导入路径 可以正确定位模块的位置;

标准库模块

  1. time 时间:
    • time.time():当前时间戳,1970年1月1日到现在经过的秒数;
    • time.localtime():时间元组,年月日时分秒,星期,年的天数,夏令时偏移量;
    • time.localtime(时间戳):接收时间戳的参数,可以将时间戳转变为一个时间元组;
    • time.mktime(时间元组):可以将一个时间元组转变为一个时间戳;
    • time.strftime("%Y年%m月%d日", 时间元组):按指定规则,格式化时间元组;
    • time.strptime(时间字符串, "%Y年%m月%d日"):按指定规则,转换为时间元组;

二、异常处理

异常:父类 Exception

  1. 定义:运行时检测到的错误;
  2. 现象:当异常发生时,程序不会继续运行,而是转到函数的调用语句;
  3. 常见的异常类型:
    • NameError:名称异常,变量未定义;
    • TypeError:类型异常,不同类型的数据进行运算;
    • IndexError:索引异常,索引超出范围;
    • AttributeError:属性异常,对象没有对应名称的属性;
    • KeyError:没有对应名称的键;
    • NotImplementedError:未实现异常,尚未实现的方法;

处理:

  1. 作用:将程序由异常状态转为正常流程;

  2. 统一处理:except 可以接收一个异常对象,使用 as 起别名,可调用异常的内部方法;

    python 复制代码
    def calculate():
        try:
            10 / int(input("请输入整数:"))
        except:
            print("出错了")
            
    def calculate2():
        try:
            10 / int(input("请输入整数:"))
        except Exception as e:	# 起别名
            print(e.args[0])
  3. except语句,针对不同的错误,做相应的处理:

    python 复制代码
    def calculate():
        try:
            10 / int(input("请输入整数:"))
        except ValueError:
            print("输入的不是整数")
        except ZeroDivisionError:
            print("不能除零")
  4. else语句,配合expect使用,没错误时执行:

    python 复制代码
    def calculate():
        try:
            10 / int(input("请输入整数:"))
        except ValueError:
            print("输入的不是整数")
        else:
            print("没有错误时执行,搭配except使用,不能单独存在")
  5. finally语句:

    python 复制代码
    def calculate():
        try:
            10 / int(input("请输入整数:"))
        except ValueError:
            print("输入的不是整数")
        finally:
            print("一定会执行的语句")

raise 语句

  1. 作用:主动抛出异常,让程序进入异常状态;
  2. 目的:人为抛出异常,快速传递错误信息,比层层 return 速度要快;
  3. 格式:raise Exception("错误信息")
  4. 自定义异常类:继承Exception类,封装异常的数据;

三、迭代

每一次对过程的重复称为一次迭代,每一次迭代的结果将会作为下一次迭代的初始值;

:for循环一次,计算一个,返回一个;所有不会撑爆内存。

可迭代对象 iterable

for循环原理:可迭代对象具有__iter__()方法;

  • __iter__():获取迭代器对象,可迭代对象 (集合、元组等) 调用;
  • __next__():获取下一个元素,迭代器对象 (iterator) 调用;
python 复制代码
iterator = list01.__iter__()

while True:
    try:
        print(iterator.__next__())
    except StopIteration:
        break

迭代器对象 iterator

iterator:可迭代对象具有__iter__()方法,为迭代对象计数,长度大于可迭代对象停止迭代;
3.

yield 关键字

  1. 程序执行过程:

    • 调用 __iter__() 程序不执行;

    • 调用 __next__() 才会执行;

    • 执行至 yield 暂时离开;

    • 再次调用 __next__() 继续执行离开时的后续代码;

  2. 执行原理:

    • 程序将 yield 前面的代码定义到next方法中;
    • 程序将 yield 后面的代码作为next的返回值;
    • yield 不会停止代码的执行,故 yield 后面的代码也执行;
    python 复制代码
    class MyRange2:
        def __init__(self, data):
            self.__data = data
    
        def __iter__(self):
            begin = 0
            while self.__data > begin:
                yield begin
                begin += 1
    
    
    for item in MyRange2(5):
        print(item)

五、生成器 generator

  1. 定义:能够动态(循环一次)提供数据的可迭代对象;

  2. 作用:循环过程中,根据某种算法推算数据,从而节省内存空间。数据量越大越明显;

  3. 以上作用也称为 延迟操作 / 惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次性计算出所有结果;

内置生成器:

  1. 枚举函数 enumerate()
    1. 语法:
      • for 变量 in enumerate(可迭代对象)
      • for 索引,元素 in enumerate(可迭代对象)
    2. 作用:遍历可迭代对象时,可以将索引和元素组合为一个元组;
  2. 压缩函数 zip() :
    1. 语法:
      • for 变量 in zip(可迭代对象1,可迭代对象2)
      • for 索引,元素 in zip(可迭代对象,可迭代对象2)

生成器函数:

  1. 定义:含有 yield 关键字的语句的函数,返回值为生成器对象;

  2. 语法:

    • 创建:__iter__() 函数,内部加入 yield 关键字

      python 复制代码
      def get_list():		# 生成新列表,每项比原列表的值大10
          for item in list01:
              yield item +10
    • 调用:for循环语句自动调用

生成器表达式:

  1. 语法:

    • 格式一:变量 = ( yield 返回值 for元素 in 可迭代对象)

    • 格式二:变量 = ( yield 返回值 for元素 in 可迭代对象 if条件)

      python 复制代码
      generate01 = (item +10 for item in list01)
      
      for item in generate01:
          print(item)
  2. 惰性操作:

    • 优点:节省内存;
    • 缺点:不能灵活访问每一项,无法使用索引、切片操作;
  3. 立即操作:

    • 优点:灵活访问每一项,可以使用索引、切片操作;
    • 缺点:占用内存;
  4. 惰性操作 ==> 立即操作:

    • 将生成器结果转换为容器(列表、元组、集合等)
    • 例如:list01 = list(item +10 for item in list01)

六、函数式编程:

  • 定义:用一系列函数解决问题。

  • 理论支柱:

    • 函数可以赋值给变量,复制后变量绑定函数;
    • 允许将函数作为参数传入另一个函数;
    • 允许函数返回另一个函数;
  • 高阶函数:将函数作为参数或返回值的函数。

    • 内置高阶函数:
    • map(函数,可迭代对象):根据可迭代对象,根据每一项映射出新的可迭代对象;
      • filter(函数,可迭代对象):过滤出符合条件的元素;
      • sorted(可迭代对象, key = 函数,reverse = 布尔值):排序,无需通过返回值传递结果
      • max(可迭代对象, key = 函数):最大值
      • min(可迭代对象, key = 函数):最小值

函数作为参数:

  1. 传入时不能带括号,否则直接会执行,而是将函数名传入,这样即可在方法内部再执行;

lambda表达式(匿名函数):

  1. 格式:lambda 参数:方法体,例如:lambda num:num == 0
  2. 作用:
    • 作为实参传递给函数,语法简洁优雅,可读性高;
    • 调用完毕立即销毁,减少代码耦合度;
  3. 注意:
    • 若无形参可不填;
    • 不能进行赋值操作;
    • 方法体只支持一行语句;
  4. 变体:
    • 单个参数:lambda a: a==0
    • 多个参数:lambda a, b, c: a==b==c
    • 没有参数:lambda : '无参数'
    • 没参数,没返回值:lambda a: print('无返回值')

外部嵌套作用域:Enclosing

python 复制代码
def fun01():
    a = 10		# 局部变量,外部嵌套变量
    def fun02():
        b = 20		# 局部变量
        print(a)		# 此时可读取外部嵌套变量,却不能修改
        nonlocal a		# 使用nonlocal声明外部嵌套变量后,才可修改,与global类似
        a = 20		# 修改外部嵌套变量

函数作为返回值:

逻辑连续,当内部函数被调用时,不脱离当前的逻辑;
1.

复制代码
  #### 闭包:

  1. 闭包说明:

     1. 非嵌套函数:调用时,在内存中开辟栈帧;函数执行完毕,栈帧释放,局部变量销毁;
     2. 嵌套函数:外部函数执行完毕后,不会释放栈帧,销毁局部变量;而是留给内部函数继续使用;
  2. 三要素:

     * 必须有一个内嵌函数;
     * 内嵌函数必须引用外部函数中的变量;
     * 外部函数返回值必须是内嵌函数;
  3. 语法:

     ```python
     def 外部函数名(参数):
         外部变量
         def 内部函数名(参数):
             nonlocal 外部变量		# 声明外部函数,而不是新创建一个
             使用外部变量
     ```

  4. 优缺点:

     1. 优点:内部函数可以使用外部函数;
     2. 缺点:外部变量会一直存在于内存中;
  5. 作用:为了实现函数装饰器;

  6. 应用:

     ```python
     def fun01(money):
         def fun02(num):
             nonlocal money
             if money > num:
                 money -= num
                 print("余额:", money)
             else:
                 print("余额不足")

         return fun02		# 返回值为一个函数


     fun03 = fun01(1000)		# 调用函数1,返回值为一个函数fun03
     fun03(200)			# 调用返回的函数,这时,局部变量不会销毁
     fun03(400)			# 调用返回的函数
     fun03(500)			# 调用返回的函数
     ```
复制代码
  #### 装饰器 decorator:拦截原函数,使其功能更强大

  1. 定义:在不改变原函数的调用以及内部代码的情况下,为其添加新的功能;

  2. 语法:

     ```python
     def 装饰器名称(func):
         def 内嵌函数名称(*args, **kwargs):
             '需要添加的新功能'
         	return func(*args, **kwargs)
     	return 内嵌函数名称

     # 调用
     原函数上添加注解:@装饰器名称
     ```

  3. 例如:

     ```python
     def add_name_to_say(func):		# 装饰器方法
         def wrapper(*args, **kwargs):
             print(func.__name__)

             return func(*args, **kwargs)

         return wrapper


     @add_name_to_say		# 调用装饰器
     def say_hello():
         print("hello")


     @add_name_to_say
     def say_goodbye():
         print("goodbye")


     say_hello()
     say_goodbye()
     ```

七、python语言基础 (总结) :

内存管理机制:

  • 引用计数:

    1. 每个变量存储对象地址时,引用计数都会自增1;

    2. 每个变量与对象引用断开时,引用计数都会自减1;

    3. 如果引用计数为0,对象则被释放;

    • 缺点:解决方式:标记清除
      • 循环引用:垃圾引用垃圾,导致无法释放内存;
  • 标记清除:扫描内存,查看是否存在无法访问的内存空间;

    • 缺点:耗时长,解决方式:分代回收
  • 分代回收:每代的内存告急时,采用标记清除,将有用的数据升至下一代;

    1. 新生代:存储数据时开辟空间;
    2. 中年代:新生代满时,将有用的数据存放至此;
    3. 老年代:中年代满时,将有用的数据存放至此;
  • 内存优化:

    1. 尽少的产生内存垃圾;
    2. 对象池
    3. 手动回收:慎用!

对象池:

  1. 每次创建对象时,都会判断池中是否具有相同的对象;有,拿来用。没有,创建;
  2. 优点:提高内存的利用率;

函数参数:

复制代码
  #### 实际参数:调用函数时

  1. 位置实参:函数名(参数一,参数二)
     1. 序列实参:函数名(\*序列)
  2. 关键字实参:函数名(参数一 = 数据1,参数二 = 数据2)
     1. 字典实参:函数名(\*\*字典)
复制代码
  #### 形式参数:创建函数时

  1. 位置形参:def 函数名(形参1,形参2)

     1. 星号元组形参:def 函数名(\*args)
  2. 命名关键字形参: def 函数名(\*,形参1,形参2)

     ​ def 函数名(\*args,形参1,形参2)
     1. 双星号字典形参:def 函数名(\*\*kwargs)
  3. 默认参数:def 函数名(形参一 = 默认值2,形参二 = 默认值2)

面向对象:OOA(分析)、OOD(设计)、OOP(编程)

  1. 软件项目生命周期:
    1. 前期 -> 市场:招标、投标
    2. 中期 -> 开发:
      • 项目启动 --> 项目立项报告
      • 需求调研 --> 需求规格说明书、需求分析说明书
      • 设计开发 -->
        • 概要设计:架构、系统功能设计、关键类、关键算法
        • 详细设计:子类、类成员、数据、业务细节
        • 编码:
      • 整体测试 --> 功能、性能
      • 试运行
      • 项目验收
    3. 后期 -> 服务:运维

python核心

  1. 迭代器 --> 生成器(惰性/延迟)
  2. 函数式编程:
    • 函数作为参数:将核心逻辑传入函数
    • 函数作为返回值:闭包 --> 装饰器
      • 不改变原有功能,在原基础上增加性能
      • 装饰器:
        • 核心思想:拦截旧功能
        • 新功能与旧功能包装在一起

八、IO

  1. 定义:数据流的输入输出,在内存中进行数据交换的操作,一般认为是IO操作;

  2. 程序分类:

    • IO密集型程序:IO操作较多;
    • 计算密集型程序:计算操作较多;

文件

  1. 格式编码角度分为:文本文件、二进制文件
  2. python中把文件视为一种类型的对象;

字节串 (bytes)

  1. python3中引入字节串的概念;
  2. 字节串以字节序列值表达数据,更方便处理二进制数据;
  3. 格式:b'字符串',仅支持ASCII,例如:s = b'abc'
  4. 格式:b'字符串'.encode(),encode() 将字符串(str)转换 字节串(bytes),decode()反之;

文件读写

  1. 对文件读写的基本操作:打开文件、读写文件、关闭文件。

    • 打开文件:open(file_name, access_mode='r', buffering=-1),返回一个文件操作对象;
      • 参数一:file_name,文件名称;
      • 参数二:access_mode ,打开文件的方式,默认为 'r' ;
        • r:以读的方式打开,文件必须存在。
        • w:以写的方式打开,无法获取文件内容。文件不存在则创建;文件存在则清空文件内容。
        • a:以追加模式打开,不会清空文件内容,而是在后面继续写。
        • r+:以读写模式打开,文件必须存在。
        • w+:以读写模式打开。
        • a+:以读写模式打开,追加模式。
        • rb:以二进制读模式打开,同r。
        • wb:以二进制写模式打开,同w。
        • ab:以二进制追加模式打开,同a。
        • rb+:以二进制读写模式打开,同r+。
        • wb+:以二进制读写模式打开,同w+。
        • ab+:以二进制读写追加模式打开,同a+。
      • 参数三:buffering ,默认-1,使用系统默认的缓冲机制;1 指行缓冲。
        • 缓冲区刷新条件:
          1. 缓冲区被写满;
          2. 程序执行结束,或文件对象被关闭;
          3. 行缓冲遇到换行符( "\n" );
          4. 主动调用 flush() 函数;
  2. 说明:

    1. 文本文件:可以用文本或二进制方式打开;
    2. 二进制文件:必须使用二进制方式打开;
  3. 文件的操作:

    1. 打开文件:

      python 复制代码
      file01 = open('file/test.txt', 'r') # 只读,文件必须存在
      file01 = open('file/test.txt', 'w') # 只写,不存在则创建
      file01 = open('file/test.txt', 'a') # 追加,append
    2. 读写操作:

      python 复制代码
      # 写入文件, 区别writelines(),writelines()可以写入多行,write()只能写入一行
      file01.write(str01)
      file01.writelines(str01)
      
      # 读取文件
      print(file01.read(5))  # 读取5个字符, 不包括换行符, 不给参数默认读取全部
      print(file01.readline())  # 读取一行,换行符也读取,但是不会返回换行符,只返回一行,如果要返回换行符,可以使用readlines()
      print(file01.readlines())  # 读取所有行,返回一个列表,每一行作为一个元素
      
      # 迭代特性
      for line in file01:
          print(line)  # 一次读取一行
    3. 关闭文件:

      python 复制代码
      file01 = open('file/新建文本文档.txt', 'r')
      file01.close() # 关闭资源
    4. with语句块:(语句块结束,文件则自动销毁,无需调用close方法)

      python 复制代码
      # 等价于 f = open('file/test.txt', 'r')
      with open('file/test.txt', 'r') as f:
          data = f.read()
          print(data)
    5. 文件拷贝:

      py 复制代码
      rf = open('C:/Users/范亚鑫/Desktop/20000000.xlsx', 'rb')
      wf = open('C:/Users/范亚鑫/Desktop/40000000.xlsx', 'wb')
      
      while True:
          line = rf.read(1024)
          if not line:
              break
          wf.write(line)
      
      rf.close()
      wf.close()
  4. 文件偏移量:

    1. 定义:对文件进行操作时,系统会自动生成一条记录,记录了对文件的一系列操作,例如读写的位置,下次操作会自动从记录的位置进行操作。
    2. 注意:
      • 读和写用的是同一个偏移量;
      • 每次调用open函数时,偏移量都将刷新,r / w 偏移量处于文件开头,a 偏移量处于末尾;
    3. 基本操作:
      • tell() 函数:获取当前的偏移量大小;
      • seek(offset, whence) 函数:更改文件偏移量的位置;whence必须二进制可选 1 / 2;
        • offset:正数向后偏移,负数向前偏移
        • whence:可省,默认0;0指文件开头算起;1指当前位置开始,2指文件末尾算起;
      • 空洞文件:指文件内容很小,却占用了很大空间,用于占用内存,为后续操作做准备;
  5. 文件描述符:

    • 定义:系统中每一个IO操作都会分配一个整数编号,这个编号就是文件描述符;
    • fileno() 函数:获取文件描述符;
  6. 文件管理函数:os模块

    • os.path.getsize():获取文件大小;
    • os.listdir('path'):path为目录名,获取目录内的文件列表;
    • os.path.exists():判断文件是否存在;
    • os.path.isfile('filename'):filename为文件名,判断文件是否为普通文件;
    • os.remove('filename'):filename为文件名,删除文件

九、网络编程基础

未完待续...

相关推荐
hbwhmama8 分钟前
python高级变量XIII
python
慕y27417 分钟前
Java学习第十六部分——JUnit框架
java·开发语言·学习
费弗里39 分钟前
Python全栈应用开发利器Dash 3.x新版本介绍(3)
python·dash
peace..1 小时前
温湿度变送器与电脑进行485通讯连接并显示在触摸屏中(mcgs)
经验分享·学习·其他
dme.1 小时前
Javascript之DOM操作
开发语言·javascript·爬虫·python·ecmascript
teeeeeeemo1 小时前
回调函数 vs Promise vs async/await区别
开发语言·前端·javascript·笔记
加油吧zkf1 小时前
AI大模型如何重塑软件开发流程?——结合目标检测的深度实践与代码示例
开发语言·图像处理·人工智能·python·yolo
t_hj1 小时前
python规划
python
czhc11400756631 小时前
Linux 76 rsync
linux·运维·python
软件黑马王子2 小时前
C#系统学习第八章——字符串
开发语言·学习·c#