我使用 Python 2.6 作为批处理脚本替换。它将通过双击启动,因此用户将丢失/忽略所有到 stdout 的输出。所以,我决定添加日志,为了简单起见,我为此编写了一个类。这个想法是我可以Logging.Logger
在我的代码中的任何地方使用,并且记录器将准备就绪。
我希望一个目录中的旧日志文件不超过 10 个,所以我手动清除旧日志文件。我还没有通过 API 找到这样的功能,而且我很偏执,想要记录所有内容,如果日志目录中有文件名意外的事实。
所以,下面是我对此类的尝试,但是当我尝试测试(运行)它时出现错误:
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "C:/AutomationScripts/build scripts/Deleteme.py", line 6, in <module>
class Logging:
File "C:/AutomationScripts/build scripts/Deleteme.py", line 42, in Logging
__clearOldLogs(dummySetting)
File "C:/AutomationScripts/build scripts/Deleteme.py", line 38, in __clearOldLogs
_assert(Logger, 'Logger does not exist yet! Why?')
NameError: global name '_assert' is not defined
>>>
是的,我来自 Java/C# 背景。我可能没有以“Pythonic”的方式做事。请帮我做正确的事,并请给出一个可行的完整答案,而不是简单地指出我知识中的漏洞。我相信我已经提供了足够的代码示例。抱歉,如果没有设置类,它将无法运行,但希望您能理解。
# This file has been tested on Python 2.6.*. For Windows only.
import logging # For actual logging
import tkMessageBox # To display an error (if logging is unavailable)
class Logging:
"""
Logging class provides simplified interface to logging
as well as provides some handy functions.
"""
# To be set when the logger is properly configured.
Logger = None
@staticmethod
def _assert(condition, message):
""" Like a regular assert, except that it should be visible to the user. """
if condition: return
# Else log and fail
if Logger:
Logger.debug(traceback.format_stack())
Logger.error('Assert failed: ' + message)
else:
tkMessageBox.showinfo('Assert failed: ' + message, traceback.format_stack())
assert(condition)
@staticmethod
def _removeFromEnd(string, endString):
_assert(string.endswith(endString),
"String '{0}' does not end in '{1}'.".format(string, endString))
return string[:-len(endString)]
def __clearOldLogs(logSettings):
"""
We want to clear old (by date) files if we get too many.
We should call this method only after variable 'Logger' has been created.
"""
# The following check should not be necessary from outside of
# Logging class, when it is fully defined
_assert(Logger, 'Logger does not exist yet! Why?')
# Do more work here
def __createLogger(logSettings):
logFileName = logSettings.LogFileNameFunc()
#_assert(False, 'Test')
logName = _removeFromEnd(logFileName, logSettings.FileExtension)
logFileName = os.path.join(logSettings.BaseDir, logFileName)
# If someone tried to log something before basicConfig is called,
# Python creates a default handler that goes to the console and will
# ignore further basicConfig calls. Remove the handler if there is one.
root = logging.getLogger()
if root.handlers:
for handler in root.handlers:
root.removeHandler(handler)
logging.basicConfig(filename = logFileName, name = logName, level = logging.DEBUG, format = "%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(logName)
return logger
# Settings is a separate class (not dependent on this one).
Logger = __createLogger(Settings.LOGGING)
__clearOldLogs(Settings.LOGGING)
if __name__ == '__main__':
# This code section will not run when the class is imported.
# If it is run directly, then we will print debugging info.
logger = Logging.Logger
logger.debug('Test debug message.')
logger.info('Test info message.')
logger.warning('Test warning message.')
logger.error('Test error message.')
logger.critical('Test critical message.')
欢迎提出相关问题、风格建议和完整答案。谢谢!