Python 全局名称记录器未通过类定义?

Python 全局名称记录器未通过类定义?,python,logging,undefined,global,Python,Logging,Undefined,Global,我无法将logger作为全局名称。。。我在一个普通脚本中尝试了它,后来又尝试在python cli中调试,但显然这超出了我的能力范围… (正如您会注意到的,我尝试在任何地方定义logger global,但也没有,没有成功) 在python cli程序中: import time import datetime import subprocess import re import glob import logging from daemon import runner from lockfil

我无法将logger作为全局名称。。。我在一个普通脚本中尝试了它,后来又尝试在python cli中调试,但显然这超出了我的能力范围…
(正如您会注意到的,我尝试在任何地方定义logger global,但也没有,没有成功)

在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无法访问您在其他模块中定义的记录器

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

“全局”变量仅在单个模块中是全局的,因此您的DoorcamExample.py无法访问您在其他模块中定义的记录器


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

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

此外,“global”关键字仅在函数中有意义-在模块顶级定义的每个名称根据定义都是模块的全局名称-并且只有在您确实希望在函数中重新绑定该名称时才有用(因此Python知道您不是在创建局部变量)


wrt/loggers naming,最简单、更有效的解决方案是为每个模块创建一个记录器,只需传递当前模块的名称(即“magic”变量
\uuuuuu name\uuuuu
),可执行脚本除外(将命名为“main”)

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

此外,“global”关键字仅在函数中有意义-在模块顶级定义的每个名称根据定义都是模块的全局名称-并且只有在您确实希望在函数中重新绑定该名称时才有用(因此Python知道您不是在创建局部变量)


wrt/loggers naming,最简单、更有效的解决方案是为每个模块创建一个记录器,只需传递当前模块的名称(即“magic”变量
\uuuuuu name\uuuuu
),可执行脚本除外(将命名为“main”)

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

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

“全局”变量仅在单个模块中是全局的,因此您的
DoorcamExample.py
无法访问您在其他模块中定义的
logger
。@BrenBarn:您应该将注释作为答案重新发布。“全局”变量仅在单个模块中是全局变量,因此您的
DoorcamExample.py
无法访问您在其他模块中定义的
logger
。@BrenBarn:您应该将注释作为答案重新发布。“Class”是模块的定义,还是DoorbellExample.py脚本?(换句话说,一个模块是否可以包含多个类,它们是否共享全局名称?)@ExploWare:一个模块(基本上)是一个Python代码文件。是的,一个模块可以包含很多类。不知道“共享全局名称”是什么意思。正如我所说,名称在模块中是全局的,所以是的,如果在模块中创建一个全局变量,那么该模块中的所有类都会看到它。“Class”是模块的定义,还是DoorbellExample.py脚本?(换句话说,一个模块是否可以包含多个类,它们是否共享全局名称?)@ExploWare:一个模块(基本上)是一个Python代码文件。是的,一个模块可以包含很多类。不知道“共享全局名称”是什么意思。正如我所说,名称在模块中是全局的,所以是的,如果在模块中创建一个全局变量,那么该模块中的所有类都将看到它。
#!/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