黑马python入门(4):python基础(序列,异常,操作文件,模块包,日志调试信息)

python在线手册  https://docs.python.org/zh-cn/3/

序列

str


  • 声明:test_str=abcedf”  也可以保留字符串里面的格式

      test_str=””“

    <html>
<title>\r\n测试标题</title>
<body>
<span>hello world</span>
</body>
</html>"

       ””“

  • 长度: len(test_str)
  • 元素增: join()   分隔符.join(字符串1,字符串2) 或者 字符串1+ 字符串2
  • 元素减:del(test_str)
  • 元素改:test_str = “bcdef”
  • 元素查: find()来找 还不会报错  in not也可以判断是否存在 但是不如find方便
  • 元素输出: test_str[2
  • 元素切割 :test_str[1:5]
  • 遍历:for v in test_str:就可以
  • 排序: 没有  但是可以转成list类型然后排序就好 再用join拼接成字符串就好

tuple

  • 本质:一个无法修改的数字索引数组
  • 声明:test_tuple=(1, 2, 3, 4, 5小括号声明 注意 声明一个元素的元组 的格式有点变化  test_tuple=(1,)
  • 长度: len(test_tuple)
  • 元素增: 固定无法操作
  • 元素减:固定无法操作
  • 元素改:固定无法操作
  • 元素查: in not in判断是否内容是否在tuple中存在 但是无法确定位置  官方使用index()来确定位置下标但是报错 还是用自己的index_plus()来解决吧
  • 元素输出: test_tuple[2这是中括号 而不是元组声明的小括号
  • 元素切割 :test_tuple[1:5]
  • 遍历:for v in aa_tuple:就可以
  • 排序:固定无法操作


小知识:序列查找函数index()和index_plus

index()是查找序列元素并返回找到的元素下标的函数 但是美中不足是 找不到却会报错 导致整个代码的崩溃

不知道其他人是怎么解决这个问题的 我用异常来控制报错暂时解决这个问题

复制代码
def index_plus(ob, __value):
    """
    :param ob: 要查找的序列
    :param __value: 要找的内容
    :return: int 找不到返回-1 找的到返回下标
    function:index的升级版  解决了找不到报错的问题
    """
    try:
        temp1 = ob.index(__value)
    except:
        temp1 = -1
    else:
        pass
    finally:
        return temp1
复制代码
import zjl
aa_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(zjl.index_plus(aa_tuple,8))  # 7
print(zjl.index_plus(aa_tuple,10))  # -1


list

  • 本质:一个数字索引数组
  • 声明:test_list=[1, 2, 3, 4, 5]
  • 长度: len(test_tuple)
  • 元素增:
  1. test_list.append(新元素)->自动在list末尾添加新元素  实际上等于test_list.insert(len(test_list), 新元素)  insert是可以在list任何位置插入新元素的 
  2. list.insert(插入的下标,插入的元素内容)
  • 元素减:
  1.      list.pop(删除的元素下标)
  2.      list.remove(删除元素的内容)
  3.      list.pop(len(list)-1)删除末尾的元素
  • 元素改:test_list[2] = 23
  • 元素查: in not in判断是否内容是否存在 但是无法确定位置 使用index_plus()来确定位置下标
  • 元素输出: test_list[2这是中括号 而不是元组声明的小括号
  • 元素切割 :test_list[1:5]
  • 遍历:for v in test_list:就可以
  • 排序:list.sort() list.reverse()
  • 复制  test_list.copy() 因为列表字典这些都是传地址的 所以为了不干扰到原始的列表字典 只能用命令复制一个和原始列表字典一样的变量 但是内存地址完全独立 这样我们修改新的变量不会影响到原始数据
  • 清空  test_list.clear()

dict

  • 本质:一个非数字索引的table 不能是数字索引 是数字索引就是set了
  • 声明:test_dict=(name”:”zjl”,

                                 “age”:18,

                                 “sex”:True,

                                 “adress”:”shandong”}

  • 长度: len(test_dict)
  • 元素增: test_dict[“id”] = 00023
  • 元素减:test_dict.pop(要删除的元素的key)
  • 元素改:test_dict[“id”] = 00024
  • 元素查: in not in判断是否内容是否存在 但是无法确定位置  使用index_plus()来确定位置下标
  • 元素输出: test_dict[2这是中括号 而不是元组声明的小括号
  • 遍历:for k, v in test_dict.items():就可以 注意items返回的是[(”name”,”zjl”), (”age”,18), (”sex”,True), (”adress”,”shandong”)]
  • 排序:只能转成list 然后list.sort()排序了  实际上字典的元素本来就没什么顺序
  • 合并: 2字典合并为一个 test_dict.update(新字典)  如果两个字典的Key有冲突 后面的字典会覆盖前面的
  • 复制  test_dict.copy() 因为列表字典这些都是传地址的 所以为了不干扰到原始的列表字典 只能用命令复制一个和原始列表字典一样的变量 但是内存地址完全独立 这样我们修改新的变量不会影响到原始数据
  • 清空 空字典 test_dict.clear()

set

  • 本质:一个元素内容不重复的集合 没有key 无论是数字key还是非数字key 并且集合的元素必须是不可变类型就是说 集合内必须是数字 字符串 元组这种不可变元素 一般是用来求交集并集差集的
  • 声明:test_set=(name”, ”zjl”, 18, (12, 34)或者 set(字符串列表元素或者range())  test_set=([“name”, ”zjl”, 18, (12, 34)])
  • 长度: len(test_set)
  • 元素增: test_set.add(元素)
  • 元素减:test_set.discard(删除元素内容) 
  • 元素改:没有Key来标识每个元素 无法对集合的元素进行修改 除非你重新声明 无法类似 test_dict[0] = 11  XXX
  • 元素查: in not in判断是否内容是否存在
  • 元素输出: 没有Key来标识每个元素 无法
  • 遍历:for v in test_set就可以
  • 排序:只能转成list 然后list.sort()排序了 
  • 交集并集差集: & | -
print({1,2} & {2,3,4})  # {2}
print({1,2} | {2,3,4})  # {1, 2, 3, 4}
print({1,2} - {2,3,4})  # {1}
  • 复制  test_set.copy() 因为这些都是传地址的 所以为了不干扰到原始的列表字典 只能用命令复制一个和原始列表字典一样的变量 但是内存地址完全独立 这样我们修改新的变量不会影响到原始数据
  • 清空 空字典 test_set.clear()

https://www.cnblogs.com/hukey/p/9242339.html


序列的公共方法和属性

  1. *  +
  2. in not in
  3. len()
  4. del()
  5. max() min() 字典的是获取Key的最大最小


异常

完整的异常处理结构

复制代码
import traceback
import logging # 导入日志模块
logger = logging.getLogger("traceback_test") # 配合 traceback.format_exc 输出更详细的情况
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
datefmt="%d-%m-%Y:%H:%M:%S")
try:
        # ==================主代码=============================
        # a = 1/a
        raise Exception("自定义异常抛出")  # 自己抛出异常 可以自定义个异常类 也可以不用想太多直接用这个方式即可
    except ValueError as e:  # 同时应对多种异常的写法
        logging.debug("数字格式异常")
        logging.debug(repr(e))  # 返回普通的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except ArithmeticError as e:  # 同时应对多种异常的写法
        logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))            # 输出更多的反馈信息
    except (ValueError, ArithmeticError): # 同时应对多种异常的写法
        logging.debug("程序发生了数字格式异常、算术异常之一")
    except Exception as e:  # Exception as e 放在else之前表示 如果上面都没找到错误应对 那么剩下的异常都归这里
        # 输出错误信息 但是并没有太详细 更加详细复杂的错误反馈需要用到 traceback 模块
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))            # 输出更多的反馈信息
    else:
        logging.debug("无异常")  # 没发生异常就跳转到这里
    finally:
        logging.debug("不管有无异常都要执行这")  # 不管有无异常都要执行这
复制代码


异常处理的原理

理解异常类型

异常其实都是一个类 这些异常的关系是如下

image

所有异常的父类都是BaswException类  常见的细化的类都是BaswException类的子类Exception类的子类 我们常用的自定义异常类也要以Exception为父类才可以

平时代码里面出现的异常都是这些底层的子类的实例而已


异常运行的流程

首先Python解释器 遇到的错误 就是抛出一个异常 我们用try except 结构来接收这个异常的实例 然后根据异常实例的类型的不同 有针对性的进行处理


定义自己的异常类

1.命名是大坨峰法

2.父类都是Exception

3.try except里面可以添加自定义类型来针对处理了  如果不需要这样 就不用自定义异常类了 直接Exception的实例就可以了

复制代码
class SignFailError(Exception):
    """
        签到失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "SignFailError:{} ".format(repr(self.value))


class LogFailError(Exception):
    """
        登录失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "LogFailError:{} ".format(repr(self.value))


class RegisteFailError(Exception):
    """
        注册失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "RegisteFailError:{} ".format(repr(self.value))



def main():
    logging.debug("======start=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))  # 标志着调试开始
    e = None
    a = 0
    try:
        # ==================主代码=============================
        # a = 1/a
        # raise Exception("自定义异常抛出")  # 自己抛出异常 可以自定义个异常类 也可以不用想太多直接用这个方式即可
        raise SignFailError("签到失败")
    except ValueError as e:  # 同时应对多种异常的写法
        logging.debug("数字格式异常")
        logging.debug(repr(e))  # 返回普通的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except ArithmeticError as e:  # 同时应对多种异常的写法
        logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except SignFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except LogFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except RegisteFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except (ValueError, ArithmeticError):  # 同时应对多种异常的写法
        logging.debug("程序发生了数字格式异常、算术异常之一")
    except Exception as e:  # Exception as e 放在else之前表示 如果上面都没找到错误应对 那么剩下的异常都归这里
        # 输出错误信息 但是并没有太详细 更加详细复杂的错误反馈需要用到 traceback 模块
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    else:
        logging.debug("无异常")  # 没发生异常就跳转到这里
    finally:
        logging.debug("不管有无异常都要执行这")  # 不管有无异常都要执行这
复制代码


手动抛出异常和常见用法

一般是用于让代码和异常处理分离 不过 我们也可以定义自己的异常类 来标识自己独有的异常 比如说  签到操作没有完成 但是代码没有错误 这个时候我们可以自定义一个异常类类型  然后自己命名这个异常类型的名字和提示的错误信息 发现签到操作没完成 就抛出一个SignFailError的自定义异常类型 在try except里面捕获这个自定义类型然后针对性的处理


异常信息的反馈提示

import traceback
import logging # 导入日志模块
logger = logging.getLogger("traceback_test") # 配合 traceback.format_exc 输出更详细的情况
logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息



模块 包 库 函数 类

函数

模块

本质:模块 每个py文件都是一个模块 里面包含了变量 函数  类 等等

导入方式

1.import 模块名1 [as 别名1], 模块名2 [as 别名2],…  这种调用需要 模块1.方法1()

2.from 模块名 import 成员名1 [as 别名1],成员名2 [as 别名2],…  这种可以直接调用 成员名()


不推荐 form zjl import *   因为可能模块zjl里面有和当前页面重名的函数 变量 类 等等 因为这种方式调用不用加命名空间 无法和本地的变量区分开来


导入多个相同模块的问题

一个页面导入相同模块多次 或者 main页面 导入了一个aa的模块 但是 main模块中 还调用了工具模块 而工具模块中依然导入了aa的模块 会发生什么

编译器会智能识别 只会调用一次  所以我们无需担心 在main文件调用一批模块或者第三方库 然后由于有需要 还在自定义模块里面再次调用这些东西


导入模块的本质

实际上就是将整个模块载入到内存中先编译执行 然后将整个模块的内容赋值给和模块名同名的变量 该变量类型为module

自定义模块编写说明文档

在模块开头写上即可  在模块名上停留或者ctrl+q 就可以看到这些提示 提示该模块包含的变量 类 函数等等

'''
demo 模块中包含以下内容:
name 字符串变量:初始值为“Python教程”
add    字符串变量:初始值为“http://c.biancheng.net/python”
say() 函数
CLanguage类:包含 name 和 add 属性和 say() 方法。
'''

载入特殊的有空格的或者数字开头的模块

__import__("demo text")


找不到模块文件怎么办


查看模块路径(包也是一种特殊模块 一样可以查看)

print(my_module1.__file__)

我们可以使用这个属性 获取到绝对路径

比如假设某个模块肯定位于根目录下

my_package.__file__.split(”module1”)[0]  这样就获取到了目录的绝对路径


本质:本质就是个文件夹 也是一种特殊的模块 但是这个文件夹有个特殊的__init__.py文件来管理这个特殊文件夹的内容 包含多个模块

创建包

  1. file->new->python package 创建包
  2. 在包文件夹里面创建模块文件 写入模块内的代码
  3. 在__init__.py里面 增加包内模块文件的导入语句 把模块导入进包里面

         from . import 模块名1   # 这里.就是指代当前包的包名

         from . import 模块名2

导入方式

  1. import 包名[.模块名 [as 别名]]    推荐
  2. from 包名 import 模块名 [as 别名]  
  3. from 包名.模块名 import 成员名 [as 别名]

导入包的本质

其实就是执行了__init__.py 然后把执行结果赋值给了和包名同名的变量 等待进一步的调用

查看包结构

dir(包名或者类名)


库由多个包构成


模块开发原则和py文件的基本结构

1.每个py文件都可能随时变成模块 所以我们每个py文件里面都要引入main()函数  所有要执行的代码都扔进这个main()函数里面执行

2.使用__name__来判断当前页面是作为运行还是作为模块被调用 以此来决定是否执行本页面的main()

复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# author:albert time:2020/9/6
# import random  # 导入random库
import datetime  # 日期时间模块
# import zjl
# import sys
# import test_model as tm
import traceback
import logging  # 导入日志模块
import test_pack

logger = logging.getLogger("traceback_test")  # 配合 traceback.format_exc 输出更详细的情况

# ========================================控制台====================================================
config_dict = dict()
# 作者相关
config_dict["author"] = "zjl"
config_dict["QQ"] = "1847154827"
# 日志
config_dict["islog"] = 1  # 是否开启调试
config_dict["islogfile"] = 0  # 是否输出到日志文件
config_dict["logfilepath"] = "log_" + datetime.datetime.now().strftime("%Y-%m-%d") + ".txt"


# ========================================配置函数====================================================
def config_fun(temp_config_dict):
    # 配置调试和日志
    if temp_config_dict["islogfile"] == 1:
        logging.basicConfig(filename=temp_config_dict["logfilepath"], level=logging.DEBUG,
                            format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
                            datefmt="%d-%m-%Y:%H:%M:%S")
    else:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
                            datefmt="%d-%m-%Y:%H:%M:%S")
    if temp_config_dict["islog"] == 1:
        pass
    else:
        logging.disable(logging.DEBUG)


# ========================================类函数区(或者放到一个模块里面)====================================================
class SignFailError(Exception):
    """
        签到失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "SignFailError:{} ".format(repr(self.value))


class LogFailError(Exception):
    """
        登录失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "LogFailError:{} ".format(repr(self.value))


class RegisteFailError(Exception):
    """
        注册失败
    """

    # 自定义异常类型的初始化
    def __init__(self, value):
        self.value = value

    # 返回异常类对象的说明信息
    def __str__(self):
        return "RegisteFailError:{} ".format(repr(self.value))


# ========================================本页主函数 配上异常处理部分========================================
def main():
    logging.debug("======start=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))  # 标志着调试开始
    e = None
    a = 0

    try:
        # ==================主代码=============================
        # a = 1/a
        # raise Exception("自定义异常抛出")  # 自己抛出异常 可以自定义个异常类 也可以不用想太多直接用这个方式即可
        raise SignFailError("签到失败")
    except ValueError as e:  # 同时应对多种异常的写法
        logging.debug("数字格式异常")
        logging.debug(repr(e))  # 返回普通的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except ArithmeticError as e:  # 同时应对多种异常的写法
        logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except SignFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except LogFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except RegisteFailError as e:  # 同时应对多种异常的写法
        # logging.debug("算术异常")
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # logging.debug(str(traceback.print_tb(sys.exc_info()[2])))
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    except (ValueError, ArithmeticError):  # 同时应对多种异常的写法
        logging.debug("程序发生了数字格式异常、算术异常之一")
    except Exception as e:  # Exception as e 放在else之前表示 如果上面都没找到错误应对 那么剩下的异常都归这里
        # 输出错误信息 但是并没有太详细 更加详细复杂的错误反馈需要用到 traceback 模块
        logging.debug(repr(e))  # 返回较全的异常信息,包括异常信息的类型
        # traceback.print_tb(sys.exc_info()[2])
        logger.error(traceback.format_exc(limit=3))  # 输出更多的反馈信息
    else:
        logging.debug("无异常")  # 没发生异常就跳转到这里
    finally:
        logging.debug("不管有无异常都要执行这")  # 不管有无异常都要执行这
    logging.debug("======end=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))  # 标志着调试结束


# 当前页面是入口文件才会执行main函数 被调用的时候不会执行
if __name__ == "__main__":
    config_fun(config_dict)
    main()
复制代码

文件目录操作

创建文件文件夹  


os.mkdir()   只能创建一层目录 无法递归创建

os.makedirs() 能递归创建目录 不会报错 推荐 但是如果目录已经存在了 两个函数都会报错 所以要配合os.path.exist() 使用
复制代码
temp1_path = os.getcwd() +os.sep + "log" + os.sep + "a"
        if os.path.exists(temp1_path):
            # 目录存在不用创建
            logging.debug("[%s] 已经存在" % temp1_path)
        else:
            # 目录不存在则创建
            logging.debug(os.makedirs(temp1_path))
复制代码

复制文件文件夹

shutil.copyfile("oldfile","newfile")   # oldfile和newfile都只能是文件 操作前还是要判断下是否都是文件或者都是文件夹

移动文件文件夹

shutil.move("oldpos","newpos")   # 操作前还是要判断下是否都是文件或者都是文件夹

重命名文件文件夹

os.renames(old, new)   # 递归重命名 没什么说的


删除文件文件夹

删除目录 os.rmdir(path) os.removedirs(path)(两者都不推荐 如果文件夹不为空 则删除报错)

推荐 shutil.rmtree 删除目录 不管你空不空 都删除干净

删除文件 os.remove() 删除文件一样要先判断存在再删除 因为删除的文件不在 一样要报错

复制代码
import shutil
temp1_path = os.getcwd() +os.sep + "a" + os.sep + "bb"

        logging.debug(os.listdir(temp1_path))
        if os.path.exists(temp1_path):
            # 目录存在要删除
            shutil.rmtree(temp1_path)
            # logging.debug(os.removedirs(temp1_path))
            logging.debug("[%s] 删除成功" % temp1_path)
        else:
            # 目录不存在 不用删除
            logging.debug("[%s] 不存在不用删除" % temp1_path)
复制代码


判断文件文件夹 是否存在   os.path.exists

logging.debug(os.path.exists('..\\python1')) # 可以判断文件 目录 支持相对路径和绝对路径 如果配合os.path.isfile os.path.isdir 可以进一步的判断是目录还是文件

复制代码
def file_dir_exists(temp1_path):
    """
    :param temp1_path: 要检测的路径 支持文件路径 目录路径
    :return: -1 表示不存在 0 表示存在而且是文件 1 表示存在 是文件夹
    :function:  是判断文件或者目录是否存在
    :base: 需要os模块的支持
    """
    temp1_result = -1
    if os.path.exists(temp1_path):
        if os.path.isfile(temp1_path):
            temp1_result = 0
        elif os.path.isdir(temp1_path):
            temp1_result = 1
        else:
            temp1_result = -1
    else:
        temp1_result = -1
    return temp1_result
复制代码


遍历文件夹

logging.debug(os.listdir(os.getcwd()))  # 返回一个包含当前目录下的所有文件文件夹的列表


路径拼接 os.path.join

logging.debug(os.getcwd())  # 取当前所在文件的目录绝对路径 
logging.debug(os.path.abspath("test1.py"))  # 相对转绝对地址1
logging.debug(os.path.abspath(".\\test1.py"))  # 相对转绝对地址2

logging.debug(os.path.split(a)) 将路径转换为dirname 和basename两部分的元组 相对路径也可以拆分 但是感觉怪怪的
logging.debug(os.path.dirname(a))
logging.debug(os.path.basename(a))

logging.debug(os.sep)  # 会根据当前系统情况来输出正确的路径斜线
logging.debug(os.path.join(os.path.dirname(a), os.path.basename(a)))  # 利用前面提到的这些拼接成完整路径  E:\python\test1.py
logging.debug(os.path.join(os.getcwd(), “test1.py”)  

Python的路径的斜线问题
众所周知 window下路径的斜线用\ 但是linux下的路径斜线用/ 而且在windows下手写路径写入\ 还要考虑转义字符问题\\->\ 那么我们平时Python的路径  应该怎么处理才能适应多个曹组系统
1.logging.debug(os.sep)  # os.sep 会根据当前系统情况来输出正确的路径斜线
2.logging.debug(os.path.join(".", "python", "test1111.py"))  # 把路径的部分拆开 然后用os.path.join拼接到一起 或者用os.path.dirname 或者os.getcwd() 提取出目录地址 然后用os.path.join拼接成一个完整路径  
3 Python3.4+的os.path.pathlib模块
import pathlib  # 导入pathlib
logging.debug(pathlib.Path("e:/python/test_pack/test_pack_module1.py"))  # 以正斜线来描述路径 pathlib.Path会自动根据系统返回合适的路径

open()函数
file = open(file_name [, mode='r' [ , buffering=-1 [ , encoding = None ]]])
file_name:就是要打开了文件路径 为了以防万一还是要检测下该文件是否是文件 是否存在
mode:这个都明白 常见备选的有 r r+ w w+ a a+
buffering:就是对文件操作的时候 是否开启缓冲区 但是这个参数意义不大 因为如果我们写入文本文件的时候 缓冲区必须是打开的 不然会报错 开启缓冲区的作用只是让操作 比如写入操作不会立刻执行 而是等一系列操作后 遇到close() 的时候 从缓冲区读取系列操作  一次性执行完毕 如果没遇到close但是想立刻执行则 使用flush()来实现阶段性的执行
encoding:没什么说的  文本文件使用的编码格式

读取文件内容

  1. f = open("a.txt", 'r')
  2. temp1 = f.read()
  3. print(temp1)
  4. f.close()

写入原理

我们写入文本文件的时候 缓冲区必须是打开的 不然会报错 开启缓冲区的作用只是让操作 比如写入操作不会立刻执行 而是等一系列操作后 遇到close() 的时候 从缓冲区读取系列操作 一次性执行完毕 如果没遇到close但是想立刻执行则 使用flush()来实现阶段性的执行

写入文件内容

  1. f = open("a.txt", 'w')
  2. f.write("覆盖写入")
  3. f.close()

追加文件内容

  1. f = open("a.txt", 'a')
  2. f.write("追加写入")
  3. f.close()

读取文件指定行内容

  1. f = open("a.txt", 'r')
  2. temp1 = f.readline()   # 读取一行内容
  3. print(temp1)
  4. f.close()

读取文件内容返回列表

  1. f = open('a.txt', 'r')
  2. n = open('b.txt','w+')
  3. n.writelines(f.readlines())
  4. n.close()
  5. f.close()

with as的使用 (推荐这个方式 会自动close 报错也会自动执行close)

with open(temp1_path, "r") as f:
logging.debug(f.read())
使用这种形式非常方便 就算代码内部出错了一样会自动close 推荐这个方式

日志调试信息


完整的日志调试代码

复制代码
import logging  # 导入日志模块

# =====配置调试信息======= 是否输出到文件 调试信息等级 信息格式等等  设置所在文件 设置行号 如果要变成日志输出到日志文件 则
# 日志文件:logging.basicConfig(filename='demo.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.basicConfig(level=logging.DEBUG, 
format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
datefmt="%d-%m-%Y:%H:%M:%S"
)
"""
logging.CRITICAL: 致命错误 最高等级
logging.ERROR: 用于记录错误,它导致程序做某事失败
logging.WARNING:用于表示可能的问题,它不会阻止程序的工作,但将来可能会。
logging.INFO:用于记录程序中一般事件的信息,或确认一切工作正常
logging.DEBUG:最低级别,用于小细节,通常只有在诊断问题时,才会关心这些消息
logging.disable 会把参数的错误等级和该参数下面的错误等级一起关闭 这些错误都不会出现在调试信息里面
"""
# logging.disable(logging.DEBUG)  # 控制调试信息的显示等级 控制是否显示调试信息

logging.debug("======start=======")  # 标志着调试开始

# logging.debug支持print的字符串格式化
aa = 100
logging.debug("======start=====%d==" % aa)
for i in range(10):
    logging.debug('i: ' + str(i))  # 正常的调试信息

logging.debug("======end=======")  # 标志着调试结束
复制代码

logging的强大功能 似乎print也被完全代替了  之后代码都采用logging来反馈信息

结果

image

posted @   点-滴  阅读(300)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示