全局名称记录器不是通过类定义的?

2024-09-27 23:24:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我无法将logger作为一个全局名称。。。我在一个普通的脚本中试过,后来又在python cli中试过调试,但显然是我做不到的……
(正如您将注意到的,我试图定义logger global everywhere,但如果没有它,就没有成功)

在python cli程序中:

import time
import datetime
import subprocess
import re
import glob
import logging
from daemon import runner
from lockfile import LockTimeout
import RPIO
import picamera
import atexit
#From here, it should be global right?
global logger
logger = logging.getLogger("DoorcamLog")
import DoorcamExample
doorcam=DoorcamExample.Doorcam()

返回错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "DoorcamExample.py", line 28, in __init__
    logger.info('Doorcam started capturing')
NameError: global name 'logger' is not defined

DoorcamExample.py:

#!/usr/bin/python
import sys
import os
if os.geteuid() != 0:
    # This works perfect on a Raspbian system because there's no rootpassword required
    os.execvp("sudo", ["sudo"] + sys.argv)
    print('to far!') #This should NEVER be reached, there is something wrong...
    sys.exit(1)

import time
import datetime
import subprocess
import re
import glob
import logging
from daemon import runner
from lockfile import LockTimeout
import RPIO
import picamera
import atexit




class Doorcam:
    global logger
    def __init__(self):
        logger.info('Doorcam started capturing')
        self.pollLightFile='/var/tmp/picam-pollLight'
        atexit.register(self.stopListening)

    def socket_callback(self, socket, val):
        vals=val.split()
        if len(vals) == 0 or len(vals) > 4:
            number=1
            notify=True
            trigger='Socket'
            triggernotify='Socket (value %s)'%val
        elif len(vals) == 1:
            number=int(vals[0])
            notify=True
            trigger='Socket'
            triggernotify='Socket (value %s)'%val
        elif len(vals) == 2:
            number=int(vals[1])
            notify=True
            trigger=vals[0]
            triggernotify=vals[0]
        elif len(vals) == 3:
            number=int(vals[1])
            trigger=vals[0]
            triggernotify=vals[0]
            notify=self.boolval(vals[2])
        elif len(vals) == 4:
            number=int(vals[2])
            trigger=vals[0]
            triggernotify=vals[0], [1]
            notify=self.boolval(vals[3])

        socket.send('self.upload(self.shot(filename=self.filename, number=number, trigger=trigger), notify=notify,trigger=triggernotify)')
        RPIO.close_tcp_client(socket.fileno())

    def startListening(self,channel,port=8080, threaded=True):
        #RPIO.add_interrupt_callback(channel, self.gpio_callback, pull_up_down=RPIO.PUD_DOWN, debounce_timeout_ms=1000)
        RPIO.add_tcp_callback(port, self.socket_callback)
        RPIO.wait_for_interrupts(threaded=threaded)

    def stopListening(self):
        logger.info('Stop listening')
        RPIO.stop_waiting_for_interrupts()


global logger

Tags: fromimportselfnumberlencallbacknotifysocket
3条回答

正如BrenBarn所评论的,在Python中,“global”只指当前模块的名称空间-希望如此,因为您不希望模块依赖于在导入模块的名称空间中定义的某些名称。

此外,“global”关键字只在函数中有意义——在模块的顶层定义的每个名称都是模块的全局定义——只有当您真正想在函数中重新绑定该名称时才有用(因此Python知道您不是在创建局部变量)。

wrt/logger s命名,最简单和更有效的解决方案是为每个模块创建一个记录器,并只传递当前模块的名称(即“magic”变量__name__),除了可执行脚本(将命名为“main”)。

在这种情况下,不需要程序范围的全局变量。日志模块跟踪通过调用getLogger创建的所有日志记录器,因此只要使用相同的名称,就会得到相同的日志对象。因此对logging.getLogger("DoorcamLog")的调用将在两个脚本中返回相同的对象。

“Global”变量只是单个模块中的全局变量,因此DoorcamExample.py不能访问在其他模块中定义的记录器。

在这种情况下,您不需要全局变量,因为日志模块已经维护了一个真正的全局(即从所有模块可见)日志记录器注册表。因此,如果您在任何模块中执行logging.getLogger("DoorcamLog"),您将获得对同一记录器的引用。

相关问题 更多 >

    热门问题