类中未定义全局名称logger?
我无法把logger当作全局变量使用……我在一个普通的脚本里试过,后来又在Python命令行里调试,但似乎都不行……
(你会注意到,我试着在各个地方定义logger为全局变量,但即使这样也没成功)
在Python命令行程序里:
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
正如BrenBarn所说,在Python中,“global”这个词只指当前模块的命名空间。这样设计是为了避免一个模块依赖于另一个模块中某个名字的定义。
另外,“global”这个关键词在函数中才有意义。模块顶层定义的每个名字本身就是全局的,只有在你想在函数内部重新绑定这个名字时,它才有用(这样Python才知道你不是在创建一个局部变量)。
关于日志记录器的命名,最简单有效的办法是为每个模块创建一个日志记录器,并传入当前模块的名字(也就是那个“神奇”的变量__name__
),除了可执行的脚本(这些脚本的名字会是“main”)。
1
在这种情况下,你不需要一个全局变量。日志模块会记录所有通过调用 getLogger
创建的日志记录器,只要你用相同的名字,就会得到同一个日志对象。所以在两个脚本中调用 logging.getLogger("DoorcamLog")
会返回同一个对象。
4
“全局”变量在一个模块内才算全局,所以你的 DoorcamExample.py 不能访问你在其他模块里定义的 logger。
在这种情况下,你其实不需要全局变量,因为 logging 模块本身就有一个真正的全局日志记录器注册表(也就是说,所有模块都能看到)。所以如果你在任何模块里使用 logging.getLogger("DoorcamLog")
,你都会得到同一个 logger 的引用。