全局名称记录器没有通过类定义?

时间:2014-03-11 19:33:30

标签: python logging undefined global

我无法将记录器作为全局名称...我在普通脚本中尝试了它,后来尝试在python cli内部进行调试,但它显然不在我的范围内......
(你会注意到,我试图在任何地方定义记录器全局,但也没有,没有成功)

在python cli-program中:

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

3 个答案:

答案 0 :(得分:4)

&#34;全球&#34;变量仅在单个模块中是全局变量,因此您的DoorcamExample.py无法访问您在其他模块中定义的记录器。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

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