搜尋
首頁後端開發Python教學python模組之logging

python模組之logging

Oct 20, 2016 am 11:53 AM

  在現實生活中,記錄日誌非常重要。銀行轉帳時會有轉帳記錄;飛機飛行過程中,會有黑盒子(飛行數據記錄器)記錄飛行過程中的一切。如果有出現什麼問題,人們可以透過日誌資料來搞清楚到底發生了什麼事。對於系統開發、調試以及運行,記錄日誌都是同樣的重要。如果沒有日誌記錄,程式崩潰時你幾乎就沒辦法弄清楚到底發生了什麼事。舉個例子,當你在寫一個伺服器程式時,記錄日誌是非常必要的。下面展示的就是 EZComet.com 伺服器的日誌檔案截圖。

python模組之logging

  服務崩潰後,如果沒有日誌,我幾乎沒辦法知道到底發生了錯誤。日誌不僅對伺服器很重要,對桌面圖形應用同樣十分重要。例如,當你的客戶的 PC 機程式崩潰時,你可以讓他們把日誌檔案寄給你,這樣你就可以找到問題到底出在哪裡。相信我,在不同的 PC 環境下,你永遠不會知道會有什麼奇怪的問題。我曾經就接收過這樣的錯誤日誌。

2011-08-22 17:52:54,828 - root - ERROR - [Errno 10104] getaddrinfo failed
Traceback (most recent call last):
  File "<string>", line 124, in main
  File "<string>", line 20, in __init__
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/wx._core", line 7978, in __init__
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/wx._core", line 7552, in _BootstrapApp
  File "<string>", line 84, in OnInit
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/twisted.internet.wxreactor", line 175, in install
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/twisted.internet._threadedselect", line 106, in __init__
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/twisted.internet.base", line 488, in __init__
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/twisted.internet.posixbase", line 266, in installWaker
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/twisted.internet.posixbase", line 74, in __init__
  File "h:workspaceprojectbuildpyi.win32mrdjoutPYZ1.pyz/socket", line 224, in meth
gaierror: [Errno 10104] getaddrinfo failed

  我最終發現,這個客戶的 PC 機被一種病毒感染,導致了呼叫 gethostname 函數失敗。看吧,如果沒有日誌可以檢查你怎麼可能知道這些。

列印輸出不是個好辦法

  儘管記錄日誌非常重要,但是並不是所有的開發者都能正確地使用它。我曾經看過有些開發者是這樣記錄日誌的,在開發的過程中插入 print 語句,開發結束後再移除這些語句。就像這樣:

print &#39;Start reading database&#39;
records = model.read_recrods()
print &#39;# records&#39;, records
print &#39;Updating record ...&#39;
model.update_records(records)
print &#39;done&#39;

  這種方式對於簡單腳本型程式有用,但是如果是複雜的系統,你最好不要使用這樣的方式。首先,你沒辦法做到在日誌檔中只留下極為重要的訊息。你會看到大量的訊息日誌。但是你卻找不到任何有用的資訊。你除了移除這個輸出語句之外,沒別的辦法控製程式碼,但是極有可能的是你忘了移出那些沒用的輸出。再者,print 輸出的所有資訊都到了標準輸出中,這將嚴重影響你從標準輸出中查看其它輸出資料。當然,你也可以把訊息輸出到 stderr ,但用 print 做日誌記錄的方式還是不好。

使用 python 的標準日誌模組

  那麼,怎麼樣記錄日誌才是正確的呢?其實非常簡單,使用 python 的標準日誌模組。多虧 python 社群將日誌做成了一個標準模組。它非常簡單易用且十分靈活。你可以像這樣使用日誌系統:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

logger.info(&#39;Start reading database&#39;)
# read database here

records = {&#39;john&#39;: 55, &#39;tom&#39;: 66}
logger.debug(&#39;Records: %s&#39;, records)
logger.info(&#39;Updating records ...&#39;)
# update records here

logger.info(&#39;Finish updating records&#39;)

運行的時候就可看到:

INFO:__main__:Start reading database
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records

你可能會問這與使用 print 有什麼不同呢。它有以下的優勢:

你可以控制訊息的級別,過濾掉那些不重要的訊息。

你可決定輸出到什麼地方,以及怎麼輸出。

  有許多的重要性別等級可供選擇,debug、info、warning、error 以及 critical。透過賦予 logger 或 handler 不同的級別,你就可以只輸出錯誤訊息到特定的記錄檔中,或是在偵錯時只記錄偵錯資訊。讓我們把logger 的等級改成DEBUG 再看一下輸出結果:

 logging.basicConfig(level=logging.DEBUG)

輸出變成了:

INFO:__main__:Start reading database
DEBUG:__main__:Records: {&#39;john&#39;: 55, &#39;tom&#39;: 66}
INFO:__main__:Updating records ...
INFO:__main__:Finish updating records

  正如看到的那樣,我們把logger 的等級改為DEBUG 後,調試記錄就出現在了輸出當中。你也可以選擇怎麼處理這些訊息。例如,你可以使用FileHandler 把記錄寫進文件中:

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# create a file handler

handler = logging.FileHandler(&#39;hello.log&#39;)
handler.setLevel(logging.INFO)

# create a logging format

formatter = logging.Formatter(&#39;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#39;)
handler.setFormatter(formatter)

# add the handlers to the logger

logger.addHandler(handler)

logger.info(&#39;Hello baby&#39;)

以合適的等級輸出日誌記錄

  有了靈活的日誌記錄模組後,你可以按適當的等級將日誌記錄輸出到任何地方然後配置它們。那你可能會問,什麼是合適的等級呢?在這兒我將分享一些我的經驗。

大多數的情況下,你不想閱讀日誌中的太多細節。因此,只有你在調試過程中才會使用 DEBUG 等級。我只使用 DEBUG 來獲取詳細的調試信息,特別是當數據量很大或頻率很高的時候,例如演算法內部每個循環的中間狀態。

def complex_algorithm(items):
    for i, item in enumerate(items):
        # do some complex algorithm computation

       logger.debug(&#39;%s iteration, item=%s&#39;, i, item)

在处理请求或者服务器状态变化等日常事务中,我会使用 INFO 等级。

def handle_request(request):
    logger.info(&#39;Handling request %s&#39;, request)
    # handle request here

    result = &#39;result&#39;
    logger.info(&#39;Return result: %s&#39;, result)

def start_service():
    logger.info(&#39;Starting service at port %s ...&#39;, port)
    service.start()
    logger.info(&#39;Service is started&#39;)

当发生很重要的事件,但是并不是错误时,我会使用 WARNING 。比如,当用户登录密码错误时,或者连接变慢时。

def authenticate(user_name, password, ip_address):
     if user_name != USER_NAME and password != PASSWORD:
        logger.warn(&#39;Login attempt to %s from IP %s&#39;, user_name, ip_address)
        return False
    # do authentication here

有错误发生时肯定会使用 ERROR 等级了。比如抛出异常,IO 操作失败或者连接问题等。

def get_user_by_id(user_id):
    user = db.read_user(user_id)
    if user is None:
        logger.error(&#39;Cannot find user with user_id=%s&#39;, user_id)
        return user
    return user

我很少使用 CRITICAL 。当一些特别糟糕的事情发生时,你可以使用这个级别来记录。比方说,内存耗尽,磁盘满了或者核危机(希望永远别发生 :S)。

  虽然不是非得将 logger 的名称设置为 __name__ ,但是这样做会给我们带来诸多益处。在 python 中,变量 __name__ 的名称就是当前模块的名称。比如,在模块 “foo.bar.my_module” 中调用 logger.getLogger(__name__) 等价于调用logger.getLogger(“foo.bar.my_module”) 。当你需要配置 logger 时,你可以配置到 “foo” 中,这样包 foo 中的所有模块都会使用相同的配置。当你在读日志文件的时候,你就能够明白消息到底来自于哪一个模块。

捕捉异常并使用 traceback 记录它

  出问题的时候记录下来是个好习惯,但是如果没有 traceback ,那么它一点儿用也没有。你应该捕获异常并用 traceback 把它们记录下来。比如下面这个例子:

try:
    open(&#39;/path/to/does/not/exist&#39;, &#39;rb&#39;)
except (SystemExit, KeyboardInterrupt):
    raise
except Exception, e:
    logger.error(&#39;Failed to open file&#39;, exc_info=True)

使用参数 exc_info=true 调用 logger 方法, traceback 会输出到 logger 中。你可以看到下面的结果

 ERROR:__main__:Failed to open file
 Traceback (most recent call last):
   File "example.py", line 6, in <module>
    open(&#39;/path/to/does/not/exist&#39;, &#39;rb&#39;)
 IOError: [Errno 2] No such file or directory: &#39;/path/to/does/not/exist&#39;

Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:

logger提供了应用程序可以直接使用的接口;

handler将(logger创建的)日志记录发送到合适的目的输出;

filter提供了细度设备来决定输出哪条日志记录;

formatter决定日志记录的最终输出格式。

logging模块是在2.3新引进的功能,下面是一些常用的类和模块级函数

模块级函数
logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
logging.basicConfig():用默认Formatter为日志系统建立一个StreamHandler,设置基础配置并加到root logger中

python模組之logging

每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)

Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
设置logger的level, level有以下几个级别:

python模組之logging

NOTSET 如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出

Handlers
handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

Formatters

Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S,下面是Formatter常用的一些信息

python模組之logging

设置过滤器
细心的朋友一定会发现前文调用logging.getLogger()时参数的格式类似于“A.B.C”。采取这样的格式其实就是为了可以配置过滤器。看一下这段代码:
LOG=logging.getLogger(”chat.gui.statistic”)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter(’%(asctime)s %(levelname)s %(message)s’)
console.setFormatter(formatter)
filter=logging.Filter(”chat.gui”)
console.addFilter(filter)
LOG.addHandler(console)
和前面不同的是我们在Handler上添加了一个过滤器。现在我们输出日志信息的时候就会经过过滤器的处理。名为“A.B”的过滤器只让名字带有 “A.B”前缀的Logger输出信息。可以添加多个过滤器,只要有一个过滤器拒绝,日志信息就不会被输出。当然名为“A”前缀的Logger会输出信息。另外,在Logger中也可以添加过滤器。

每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
1)    logging.StreamHandler
使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr
2)   logging.FileHandler
和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。
3)   logging.handlers.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
4)   logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨
5)   logging.handlers.SocketHandler
6)   logging.handlers.DatagramHandler
以上两个Handler类似,都是将日志信息发送到网络。不同的是前者使用TCP协议,后者使用UDP协议。它们的构造函数是:
Handler(host, port)
其中host是主机名,port是端口名
7)  logging.handlers.SysLogHandler
8)  logging.handlers.NTEventLogHandler
9)  logging.handlers.SMTPHandler
10) logging.handlers.MemoryHandler
11) logging.handlers.HTTPHandler

# encoding:utf-8
#import logging

#FORMAT = &#39;%(asctime)-15s %(clientip)s %(user)-8s %(message)s&#39;
#logging.basicConfig(format=FORMAT)
#d = {&#39;clientip&#39;: &#39;192.168.0.1&#39;, &#39;user&#39;: &#39;fbloggs&#39;}
#logger = logging.getLogger(&#39;tcpserver&#39;)
#logger.warning(&#39;Protocol problem: %s&#39;, &#39;connection reset&#39;, extra=d)

#FORMAT = &#39;%(asctime)-15s %(message)s&#39;
#logging.basicConfig(filename = "C:\\Users\\june\\Desktop\\1.txt", level = logging.DEBUG, filemode = "a", format=FORMAT)  
#logging.debug(&#39;this is a message&#39;)  
#logging.debug(&#39;test&#39;)  

#import logging
#import datetime
#
#curDate = datetime.date.today() - datetime.timedelta(days=0)
#logName =  &#39;C:\\Users\\june\\Desktop\\error_%s.log&#39; %curDate
#
#logging.basicConfig(level=logging.INFO,
#                format=&#39;%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s&#39;,
#                #datefmt=&#39;%a, %d %b %Y %H:%M:%S&#39;,
#                filename=logName,
#                filemode=&#39;a&#39;)
#
##2013-10-21 03:25:51,509 writeLog.py[line:14] INFO This is info message
##2013-10-21 03:25:51,510 writeLog.py[line:15] WARNING This is warning message
#logging.debug(&#39;This is debug message&#39;)
#logging.info(&#39;This is info message&#39;)
#logging.warning(&#39;This is warning message&#39;)import logging
import logging.config

logging.config.fileConfig("logging.conf")

#create logger
loggerInfo = logging.getLogger("infoLogger")

#"application" code
loggerInfo.debug("debug message")
loggerInfo.info("info message")
loggerInfo.warn("warn message")
loggerInfo.error("error message")
loggerInfo.critical("critical message")


loggerError = logging.getLogger("errorLogger")
loggerError.error("Error: Hello world!")
#coding=utf-8
import logging
import datetime

format=&#39;%(asctime)s - %(filename)s - [line:%(lineno)d] - %(levelname)s - %(message)s&#39;
curDate = datetime.date.today() - datetime.timedelta(days=0)
infoLogName =  r&#39;C:/Users/june/Desktop/info_%s.log&#39; %curDate
errorLogName =  r&#39;C:/Users/june/Desktop/error_%s.log&#39; %curDate

formatter = logging.Formatter(format)

infoLogger = logging.getLogger("infoLog")
errorLogger = logging.getLogger("errorLog")

infoLogger.setLevel(logging.INFO)
errorLogger.setLevel(logging.ERROR)

infoHandler = logging.FileHandler(infoLogName, &#39;a&#39;)
infoHandler.setLevel(logging.INFO)
infoHandler.setFormatter(formatter)

errorHandler = logging.FileHandler(errorLogName, &#39;a&#39;)
errorHandler.setLevel(logging.ERROR)
errorHandler.setFormatter(formatter)

testHandler = logging.StreamHandler()
testHandler.setFormatter(formatter)
testHandler.setLevel(logging.ERROR)

infoLogger.addHandler(infoHandler)
infoLogger.addHandler(testHandler)
errorLogger.addHandler(errorHandler)

#infoLogger.debug("debug message")
#infoLogger.info("info message")
#infoLogger.warn("warn message")
# # 下面这行会同时打印在文件和终端上
#infoLogger.error("error message")
#
#errorLogger.error("error message")
#errorLogger.critical("critical message")
&#39;&#39;&#39;
Created on 2016年8月18日

@author: apple
&#39;&#39;&#39;
#-*- coding:utf-8 -*-

#开发出一个日志系统,既要把日志输出到控制台,还要写入日志文件

import logging
import time
import os
import os.path

class Logger():
    def __init__(self, log_name, logger_name):
        
        &#39;&#39;&#39;
                指定保存日志的文件路径,日志级别以及调用文件
                将日志    存入到指定的文件中
    
        &#39;&#39;&#39;
        #设置日志文件名称:time.time()取得当前时间;time.localtime()取得本地时间;time.strftime()格式化日期;
        time_str = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime(time.time()))
        logname = time_str + &#39;_&#39; + log_name + &#39;.log&#39;
        
        #设置日志文件所在的路径
        log_filedir = &#39;Log&#39;
        if not os.path.isdir(log_filedir):
            print("日志文件夹 %s 不存在,开始创建此文件夹" %log_filedir)
            os.mkdir(&#39;Log&#39;)
        else:
            print("日志文件夹 %s 存在" %log_filedir)
        
        os.chdir(&#39;Log&#39;)
        
        #创建一个logger以及设置日志级别
        #logging有6个日志级别:NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL对应的值分别为:0,10,20,30,40,50
        #例如:logging.DEBUG和10是等价的表示方法
        #可以给日志对象(Logger Instance)设置日志级别,低于该级别的日志消息将会被忽略,也可以给Hanlder设置日志级别
        #对于低于该级别的日志消息, Handler也会忽略。
        self.logger = logging.getLogger(logger_name)
        self.logger.setLevel(logging.DEBUG)
        
        #创建文件handler,用于写入日志文件并设置文件日志级别
        file_handler = logging.FileHandler(logname)
        file_handler.setLevel(logging.DEBUG)
        
        #创建控制端输出handler,用于输出到控制端并设置输出日志级别
        console_handler = logging.StreamHandler()
        console_handler.setLevel(logging.DEBUG)
        
        #在控制端handler添加过滤器,将含有chat或者gui的handler信息输出
        filter = logging.Filter("chat.gui")
        console_handler.addFilter(filter)
        
        #定义handler的输出格式并将格式应用到handler
        formatter = logging.Formatter(&#39;%(asctime)s-%(name)s-%(levelname)s-%(message)s&#39;)
        file_handler.setFormatter(formatter)
        console_handler.setFormatter(formatter)
        
        #将handler加入到logger
        self.logger.addHandler(file_handler)
        self.logger.addHandler(console_handler)
        
        self.logger.debug("这个是debug日志信息")
        self.logger.info("欢迎大家来到 Python的世界")
        
        
        #将handler从logger中移除
        self.logger.removeHandler(file_handler)
        self.logger.removeHandler(console_handler)

if __name__ == &#39;__main__&#39;:       
    print(os.getcwd())
    Log = Logger(&#39;create_log&#39;, "chat.gui.statistic")
        


# 模块级函数
# 
# logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
# logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
# logging.basicConfig():用默认Formatter为日志系统建立一个StreamHandler,设置基础配置并加到root logger中
# 
# Loggers
# 
# Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
# Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
# Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
# Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

# Handlers
# 
# handler对象负责发送相关的信息到指定目的地。可以通过addHandler()方法添加多个多handler
# Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
# Handler.setFormatter():给这个handler选择一个格式
# Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

# Formatters
# 
# Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S,下面是Formatter常用的一些信息


# %(name)s                       Logger的名字
#  
# %(levelno)s                    数字形式的日志级别
#  
# %(levelname)s                文本形式的日志级别
#  
# %(pathname)s                调用日志输出函数的模块的完整路径名,可能没有
# 
# %(filename)s                  调用日志输出函数的模块的文件名
#  
# %(module)s                    调用日志输出函数的模块名
#  
# %(funcName)s                调用日志输出函数的函数名
#  
# %(lineno)d                     调用日志输出函数的语句所在的代码行
#  
# %(created)f                    当前时间,用UNIX标准的表示时间的浮 点数表示
#  
# %(relativeCreated)d        输出日志信息时的,自Logger创建以 来的毫秒数
#  
# %(asctime)s                  字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
# 
# %(thread)d                   线程ID。可能没有
# 
# %(threadName)s           线程名。可能没有
# 
# %(process)d                 进程ID。可能没有
#  
# %(message)s               用户输出的消息
&#39;&#39;&#39;
Created on 2016年8月25日

@author: apple
&#39;&#39;&#39;
import logging

logging.basicConfig(level=logging.INFO,
                    format=&#39;%(asctime)s %(name)s %(levelname)s %(message)s&#39;,
                    datefmt=&#39;%m-%d %H:%M&#39;,
                    filename=&#39;./AutoUpdate.log&#39;,
                    filemode=&#39;w&#39;)

console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter(&#39;%(name)s: %(levelname)-8s %(message)s&#39;)
console.setFormatter(formatter)
logging.getLogger(&#39;&#39;).addHandler(console)

logging.info("hello world!")


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python和時間:充分利用您的學習時間Python和時間:充分利用您的學習時間Apr 14, 2025 am 12:02 AM

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python:遊戲,Guis等Python:遊戲,Guis等Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python vs.C:申請和用例Python vs.C:申請和用例Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時的Python計劃:一種現實的方法2小時的Python計劃:一種現實的方法Apr 11, 2025 am 12:04 AM

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python:探索其主要應用程序Python:探索其主要應用程序Apr 10, 2025 am 09:41 AM

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

您可以在2小時內學到多少python?您可以在2小時內學到多少python?Apr 09, 2025 pm 04:33 PM

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。