黑马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 @ 2020-09-08 14:06  点-滴  阅读(275)  评论(0编辑  收藏  举报