Suppose you want to develop an automated script tool. The project structure is as follows. Common
This package
is the implementation of the framework function. The Scripts
directory is the test case we wrote. Scripts (please ignore other irrelevant directories).
Our requirements for the log function are as follows:
1 In order to facilitate log viewing, each script corresponds to a log file, and the log file is named after the name of the script
2 The log path and the log capacity saved by each script can be set. For example, if it is set to 5MB, the oldest log will be automatically overwritten after exceeding it
3 The log function should be easy to use and reduce the coupling with the framework business functions
Now let’s analyze the above requirements one by one.
1 To implement a log file for each script, you need to generate a log file according to the name of the use case script in the log module. The key issue here is How to get the name of the use case script in the logging module.
Commonly used methods to obtain file names are: os.getcwd()
, sys.argv[0], __file__,
Let’s take a look at the various functions:
First write the following code in a file (assumed to be test.py
):
Then in another file (assumed to be import test
in script1.py
), and then call the func
method:
Runscript1.py
, the result is:
It can be seen that os.getcwd()
obtains the directory where the script is executed, sys.argv[0]
is the absolute path name of the executed script, __file__
is the absolute path name of the file where the executed code is located.
Now it is clear, we should use sys.argv[0]
to get the name of the execution script. Since the absolute path is obtained, some processing needs to be done: sys .argv[0].split('/')[-1].split('.')[0]
2 Log capacity issue, to automatically overwrite the oldest log after exceeding the capacity, use the RotatingFileHandler
class in logging
. You can set the size of the log file and the number of backups.
So where are the log path and capacity configuration? It is obviously not good to let users directly modify the parameters of RotatingFileHandler
. It is best not to let users modify the framework file. Users only need to call the interface and write their own scripts.
The solution adopted here is to write the configuration information into a file. The XML file is more suitable as a configuration file. The user formulates the configuration by modifying the XML file, and the log module reads parameters from the XML file.
For convenience, put the XML file under Common
and name it config.xml
. The content is:
<?xml version="1.0" encoding="utf-8"?> <config> <!-- 日志保存路径 --> <logpath>E:\PythonLog</logpath> <!-- 每个脚本对应的日志文件大小,单位MB --> <logsize>8</logsize> <!-- 每个脚本保存的日志文件个数 --> <lognum>3</lognum> </config>
Reading the contents of XML files is very simple using the lxml
library. The code will be given later.
3 The log function should be easy to use and reduce the coupling with the business functions of the framework. It is best to encapsulate the log function and only provide Just use the logging interface.
The log interface can meet the above requirements in the form of a class method. Users only need to call the logging interface through the class, which can be called anywhere. It is easy to use, and there is no need to define a class instance, and there is no coupling with the framework business.
With the above analysis, let’s implement the log module.
Since the logging function is also part of the foundation of the framework, we also put the log module in the Common
package
and create a new# under Common
##log.py file, the code is as follows:
# coding: utf-8 from lxml import etree import logging.handlers import logging import os import sys # 提供日志功能 class logger: # 先读取XML文件中的配置数据 # 由于config.xml放置在与当前文件相同的目录下,因此通过 __file__ 来获取XML文件的目录,然后再拼接成绝对路径 # 这里利用了lxml库来解析XML root = etree.parse(os.path.join(os.path.dirname(__file__), 'config.xml')).getroot() # 读取日志文件保存路径 logpath = root.find('logpath').text # 读取日志文件容量,转换为字节 logsize = 1024*1024*int(root.find('logsize').text) # 读取日志文件保存个数 lognum = int(root.find('lognum').text) # 日志文件名:由用例脚本的名称,结合日志保存路径,得到日志文件的绝对路径 logname = os.path.join(logpath, sys.argv[0].split('/')[-1].split('.')[0]) # 初始化logger log = logging.getLogger() # 日志格式,可以根据需要设置 fmt = logging.Formatter('[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S') # 日志输出到文件,这里用到了上面获取的日志名称,大小,保存个数 handle1 = logging.handlers.RotatingFileHandler(logname, maxBytes=logsize, backupCount=lognum) handle1.setFormatter(fmt) # 同时输出到屏幕,便于实施观察 handle2 = logging.StreamHandler(stream=sys.stdout) handle2.setFormatter(fmt) log.addHandler(handle1) log.addHandler(handle2) # 设置日志基本,这里设置为INFO,表示只有INFO级别及以上的会打印 log.setLevel(logging.INFO) # 日志接口,用户只需调用这里的接口即可,这里只定位了INFO, WARNING, ERROR三个级别的日志,可根据需要定义更多接口 @classmethod def info(cls, msg): cls.log.info(msg) return @classmethod def warning(cls, msg): cls.log.warning(msg) return @classmethod def error(cls, msg): cls.log.error(msg) returnLet’s test it, in the scripts
script1 and
script2 Write the following codes in :
from Common.log import * logger.info('This is info') logger.warning('This is warning') logger.error('This is error')Run the two scripts respectively, and the console output is:
Log file generated:
File content:
For more articles related to using the Python script log function, please pay attention to the PHP Chinese website!

TomergelistsinPython,youcanusethe operator,extendmethod,listcomprehension,oritertools.chain,eachwithspecificadvantages:1)The operatorissimplebutlessefficientforlargelists;2)extendismemory-efficientbutmodifiestheoriginallist;3)listcomprehensionoffersf

In Python 3, two lists can be connected through a variety of methods: 1) Use operator, which is suitable for small lists, but is inefficient for large lists; 2) Use extend method, which is suitable for large lists, with high memory efficiency, but will modify the original list; 3) Use * operator, which is suitable for merging multiple lists, without modifying the original list; 4) Use itertools.chain, which is suitable for large data sets, with high memory efficiency.

Using the join() method is the most efficient way to connect strings from lists in Python. 1) Use the join() method to be efficient and easy to read. 2) The cycle uses operators inefficiently for large lists. 3) The combination of list comprehension and join() is suitable for scenarios that require conversion. 4) The reduce() method is suitable for other types of reductions, but is inefficient for string concatenation. The complete sentence ends.

PythonexecutionistheprocessoftransformingPythoncodeintoexecutableinstructions.1)Theinterpreterreadsthecode,convertingitintobytecode,whichthePythonVirtualMachine(PVM)executes.2)TheGlobalInterpreterLock(GIL)managesthreadexecution,potentiallylimitingmul

Key features of Python include: 1. The syntax is concise and easy to understand, suitable for beginners; 2. Dynamic type system, improving development speed; 3. Rich standard library, supporting multiple tasks; 4. Strong community and ecosystem, providing extensive support; 5. Interpretation, suitable for scripting and rapid prototyping; 6. Multi-paradigm support, suitable for various programming styles.

Python is an interpreted language, but it also includes the compilation process. 1) Python code is first compiled into bytecode. 2) Bytecode is interpreted and executed by Python virtual machine. 3) This hybrid mechanism makes Python both flexible and efficient, but not as fast as a fully compiled language.

Useaforloopwheniteratingoverasequenceorforaspecificnumberoftimes;useawhileloopwhencontinuinguntilaconditionismet.Forloopsareidealforknownsequences,whilewhileloopssuitsituationswithundeterminediterations.

Pythonloopscanleadtoerrorslikeinfiniteloops,modifyinglistsduringiteration,off-by-oneerrors,zero-indexingissues,andnestedloopinefficiencies.Toavoidthese:1)Use'i


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Chinese version
Chinese version, very easy to use
