学习pyqt5相关知识回顾

1. 模块

1.1 import导入

1) 模块:是一系列功能的集合体,模块名.功能名,就可以使用模块的功能

2) 首次导入模块,就会立即执行模块里面的内容

3) 当前名称空间会产生一个名字module,指向module.py产生的名称空间.我们可以使用module.name/函数名,来调用module.py里面的内容.

modlue.py文件的内存地址引用变为0的时候,该名称空间才会被回收.就是模块测试.py文件运行完毕的时候

4) 在函数内部导入模块,这个模块名是属于函数局部名称空间的,其他地方是访问不到的. 

5) 当module.py被直接运行的时候,__name__的值为__main__,当modlue.py作为模块导入时,__name__的值为模块名module.

1.2 from..import..导入

1) import导入后需要加模块名来调用模块里面的属性和功能.使用from导入后,就避免写前缀了.它会直接指向模块里面对应的功能或是变量值的内存地址.也就是说当前模块的name指向的是"张大仙"的内存地址,而不是name.

 2) from modlue import *,默认导入的就是__all__里面的名字.我们可以通过控制__all__的内容来控制导入的内容.

1.3 模块的查找顺序

1)现在内存找,内存找不到就到硬盘找。内存的查找路径是按照sys.path的列表里面依次查找的

 2)如果导入的模块和当前运行的程序不是在同一文件夹,那么可以将模块所在的文件夹,添加进入sys.path.再导入模块的时候,就可以被识别到。

3)只要在文件中间添加了此行代码,那么直接使用文件名就可以运行文件,不用再加python解释器。

 2.包

2.1 包的概念

1)包就是一个含有__init__.py文件的文件夹

2)导包的流程和导入模块的流程是一样的(导入包pack)

        ——创建名称空间(pack的名称空间)

        ——执行python文件(运行pack.py但是没有只能运行__init__.py)

        ——在执行的名称空间中产生一个名字,指向前面的名称空间(所以当前名称空间里面的pack指向的是__init__.py的名称空间)

2.2 绝对导入

1)所有被导入的文件的sys.path参照的都是执行文件的sys.path.也就是说__init__.py文件的执行路径也是'D:\\PythonData\\pythonProject\\module-7'.我们直接导入running.在sys.path里面是找不到的。它的路径下面只有game.所以导入的时候是从包的起始位置game进行导入。

但是所有的前提都是,使用者要将game所在的路径添加到环境变量里面去,不管是包被嵌套了多少层。

'D:\\PythonData\\pythonProject\\module-7\\mm\\tt“

2)导入规则

入包时凡是带.的,.的左边必须是一个包 

 

 2.3 相对导入

. 表示当前文件所在的文件夹就是__init__.py文件所在的文件夹。

.. 表示上一层文件夹

pay的当前文件夹是gg,上一层文件夹是game.从game找walking.

相对导入的范围不可超出顶级包game.

2.4 补充

如果在__init__.py文件里面并没有导入包下面的模块名,调用的时候可以直接导入logging.config,此时会先检索__init__.py里面有没有config,没有再找模块名.但是调用的时候就必须加上前缀logging.config. 

3.日志

3.1 日志基本配置

1) 日志的默认输出级别就是warning,warning以下的内容就不会输出.可以通过控制日志等级来控制日志输出 

2) 日志的基本配置包括(1.日志级别,2.日志格式,3.asctime,4.日志输出位置)

import logging

logging.basicConfig(
    # 1.日志级别
    # DEBUG:10
    # INFO:20
    # WARNING:30
    # ERROR:40
    # CRITICAL:50
    level=10,

    # 2.日志输出格式
    # %(asctime)s -> 获取当前时间
    # %(name)s -> 当前日志的名字
    # %(pathname)s -> 产生日志文件的名字
    # %(lineno)d -> 产生日日志的行
    # %(levelname)s -> 产生日志的等级
    # %(message)s -> 日志的详细内容
    format='%(asctime)s %(name)s [%(pathname)s line:%(lineno)d] %(levelname)s %(message)s',

    # 3、asctime的时间格式
    datefmt="%Y-%m-%d %H:%M:%S",

    # 4、日志输出位置:终端|文件,不指定此项配置,默认输出到终端
    filename="user.log"
)

# 日志的输出级别是可以设置的
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

输出日志的时候没有指定字符编码,所以默认使用的就是系统的编码方式.windows使用的gbk,mac和linux默认的就是UTF-8.pycharm默认是使用UTF-8打开的,所以对于windows电脑可能会出现乱码. 

2024-07-05 08:58:30 root [/Users/f7692281/PycharmProjects/other-stydy/日志/日志测试.py line:34] DEBUG debug
2024-07-05 08:58:30 root [/Users/f7692281/PycharmProjects/other-stydy/日志/日志测试.py line:35] INFO info
2024-07-05 08:58:30 root [/Users/f7692281/PycharmProjects/other-stydy/日志/日志测试.py line:36] WARNING warning
2024-07-05 08:58:30 root [/Users/f7692281/PycharmProjects/other-stydy/日志/日志测试.py line:37] ERROR error
2024-07-05 08:58:30 root [/Users/f7692281/PycharmProjects/other-stydy/日志/日志测试.py line:38] CRITICAL critical

3.2 日志配置字典

日志的基本配置可能会出现乱码的问题,并且不同将日志同时输出到文件和终端.

1)  loggers负责产生不同级别的日志,handlers负责处理不同级别的log,是输出到文件/终端,以..形式来产生log.formatters则是负责控制log的输出格式

2) 因为logging这个包在使用的时候,没有将congfig导入到__init__.py里面所以只能够使用logging.config() 

3) 可以使用没有名字的日志记录器,将多个log记录到同一个log里面.

4) 日志轮转

# _*_ coding utf-8 _*_
# george
# time: 2024/1/9上午10:46
# name: settings.py
# comment:
import logging

LOGGING_DIC = {
    "version": 1.0,
    "disable_existing_log": False,
    # 日志格式,这里可以指定多种日志格式,这里的standard...就是对应日志名字
    "formatters": {
        "standard": {
            "format": '%(asctime)s %(name)s [%(pathname)s line:%(lineno)d] %(levelname)s %(message)s',
            "datefmt": "%Y-%m-%d %H:%M:%S"},
        "simple": {
            "format": '%(asctime)s %(name)s %(levelname)s %(message)s',
            "datefmt": "%Y-%m-%d %H:%M:%S"},
        "test": {"format": '%(asctime)s %(message)s'}
    },
    "filters": {},
    # 日志处理器:将记录的日志进行处理(输出到文件/显示到控制台)
    # 可以设置多个handler不同的handler做不同的处理,做不同的配置
    "handlers": {
        "console_debug_handler": {
            "level": 20,  # 日志处理的级别限制
            "class": "logging.StreamHandler",  # 输出到终端
            "formatter": "simple",  # 日志格式
        },
        "file_info_handler": {
            "level": "INFO",
            'class': "logging.handlers.RotatingFileHandler",
            "filename": "deal.log",
            # 日志大小,10M,日志文件达到10M的时候进行轮转
            # 默认单位为字节,1KB 1024 Byte,1MB为1024KB
            "maxBytes": 800,
            "backupCount": 10,  # 日志文件保存数量的限制
            "encoding":"utf-8",
            "formatter":"standard"
        },
        "file_debug_handler": {
            "level": 10,
            "class": "logging.FileHandler",  # 保存到文件
            "filename": "test.log",  # 日志存放的路径
            "encoding": "utf-8",  # 日志文件的编码
            "formatter": "test"  # 日志格式
        },
        "file_deal_handler": {
            "level": 20,
            "class": "logging.FileHandler",  # 保存到文件
            "filename": "deal.log",  # 日志存放的路径
            "encoding": "utf-8",  # 日志文件的编码
            "formatter": "standard"  # 日志格式
        },
        "file_operate_handler": {
            "level": 20,
            "class": "logging.FileHandler",  # 保存到文件
            "filename": "operate.log",  # 日志存放的路径
            "encoding": "utf-8",  # 日志文件的编码
            "formatter": "standard"  # 日志格式
        }
    },
    # 日志记录器
    "loggers": {
        "logger1": {  # 导入时logging.getLogger时使用的app_name
            "handlers": ["console_debug_handler","file_info_handler"],  # 日志将要分配给哪个handler进行日志处理
            "level": "DEBUG",  # 日志记录的级别限制,和handlers里面的日志一起组成两层日志过滤
            "propagate": False  # 默认为True,向更高级别的日志进行传递
        },
        "logger2": {
            "handlers": ["console_debug_handler", "file_debug_handler"],  # 日志将要分配给哪个handler进行日志处理
            "level": "INFO",  # 日志记录的级别限制,和handlers里面的日志一起组成两层日志过滤
            "propagate": False  # 默认为True,向更高级别的日志进行传递
        },
        "": {
            "handlers": ["file_deal_handler","file_info_handler"],  # 日志将要分配给哪个handler进行日志处理
            "level": "INFO",  # 日志记录的级别限制,和handlers里面的日志一起组成两层日志过滤
            "propagate": False  # 默认为True,向更高级别的日志进行传递
        },
        "用户操作": {
            "handlers": ["file_operate_handler"],  # 日志将要分配给哪个handler进行日志处理
            "level": "INFO",  # 日志记录的级别限制,和handlers里面的日志一起组成两层日志过滤
            "propagate": False  # 默认为True,向更高级别的日志进行传递
        }
    }
}

4.configparser模块的读写

这个模块是用来加载一种特定格式的配置文件的.配置文件的后缀名为ini或是cfg是什么名字其实并不重要,只要让别人一看就知道你这是配置文件就可以了

  • [default]是这一部分配置的标题,名字可以随便起.是这个配置文件section.每个section里面的这些配置被叫做option.
  • 这些option的表现形式可以是=,也可以是:这两种做法都是被支持的.
  • 在这里写入的是什么就会被读取到什么.添加"",""也会被读取到.所以如果定义的option为空时,直接=后面什么都不加就可以了.

4.1 config模块的读取

# settings.ini配置
from configparser import ConfigParser
config = ConfigParser()
CONFIG_PATH = os.path.join(Base_Dir,"settings.ini")
config.read(CONFIG_PATH,encoding="utf-8")
login_user = config.get('default',"LOGIN_USER")
login_type = config.get('default',"LOGIN_TYPE")

4.2 config模块的写入

# -5.1 记录登陆的用户名和用户类型
settings.config.set("default", "LOGIN_USER", name)
settings.config.set("default", "LOGIN_TYPE", user_type)
with open(settings.CONFIG_PATH, mode="w", encoding="utf-8") as f:
        settings.config.write(f)

5.eval和exec

5.1 eval

eval主要是用来执行表达式的,它执行的代码需要一个返回结果

5.2 globals和locals 

globals()和locals() 

globals()获取的是全局名称空间里面所有的名字.

loacls()获取的是局部名称空间里面所有的名字,如果locals()在全局里面使用的话,拿到的结果和globals()是一致的,我们当前在全局,所以当前的局部就是全局.

5.3 eval剩余两个参数

  • g代表全局名称空间 
  • l代表局部名称空间
  • 现在可以将eval执行的代码想象为一段函数的子代码,g就是它能够访问到的全局名称空间,l就是它的全局名称空间.这两个参数其实都是为了往里面传参数的.如果不传全局名称空间的话,默认就会将所有全局空间里面的名字都传递进去

  • 我们不传第2和第3个参数的时候eval()是可以执行的,也就是说我们不定制全局名称空间和局部名称空间的时候.它默认会把所有全局的名字都传进去,就是globals()和locals().如果而我们定制了第2个参数,它只会传我们自定义的名字以及python内置的名字 

 

  • 表达式必须有返回值,如果没有返回值会直接报错 

5.4 exec

  • exec主要是用来执行代码块的,它的用法和eval是类似的,只是它是没有返回值的.
  • exec只会将字符串里面产生的名字,存到第三个参数里面如果我们直接在全局打印a是会报错的
  • 如果不传后面的两个参数,默认传递的就是globals()和locals(),字符串里面产生的名字会保存到locals()里面,而当前就是在全局,也就是说globals()就是locals()
  • globals()绑定了全局名称空间,locals()并没有绑定当前局部名称空间,只是一个拷贝版本的字典

 

 

5.5 系统攻击 

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值