我有一些代码应该使用syslog记录错误。登录到syslog时,我希望脚本名称和pid显示在日志本身中。
from syslog import syslog, openlog, LOG_PID
from sys import version_info
openlog(logoption=LOG_PID)
syslog('Some message')
然而,python 2.6不支持openlog,logoption和LOG_PID,我知道这个脚本将在使用python 2.7和python 2.6的机器上运行。我这样解决了。
from syslog import syslog
from sys import version_info
(major, minor, dummy1, dummy2, dummy3) = version_info
if major == 2 and minor == 7:
from syslog import openlog, LOG_PID
openlog(logoption=LOG_PID)
syslog('some message')
这样做会让人感到奇怪。这听起来不错?无论如何我还能在2.6中获得相同的功能吗?
答案 0 :(得分:3)
首先:
从同一个图书馆导入两次
我不确定你认为这个问题是什么,因为你从来没有暗示它是什么。如果多次导入库,则库实际上只会导入一次,但每次都会发生作为导入过程发生的任何名称绑定。
“但”通常不是问题,但如果您尝试使用from MODULE import NAME
语法,并且其中一个名称与模块本身具有相同的名称,则很容易让自己感到困惑。
最好的解决方案是不要这样做。例如:
import syslog
# …
syslog.openlog(logoption=syslog.LOG_PID)
如果您确实需要from
导入,请确保仅在所有其他from foo import foo
导入后执行from foo import bar
,这样可以避免任何混淆。
接下来,你的基本前提是错误的:
但是,python 2.6不支持openlog,logoption和LOG_PID
是的。 openlog
函数从一开始就在模块中。 SO有LOG_PID
。 Here are the 2.6 docs。这是我使用它:
$ python2.6
Python 2.6.7 (r267:88850, Oct 11 2012, 20:15:00)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from syslog import openlog, LOG_PID
>>> openlog('syslog', LOG_PID)
如果您在导入时遇到错误,很可能它与Python版本无关,而是与您的平台无关。正如文档所说,所有日志选项仅在“<syslog.h>
中定义时才可用”。因此,如果您的平台没有LOG_PID
,那么Python(无论是2.6还是2.7)将不会在该平台上拥有syslog.LOG_PID
。
是是的,2.6不保证openlog
接受关键字参数,而2.7确实。{1>}。但这种差异不可能导致ImportError
。防范这种情况的方法不仅仅是跳过调用2.6中的函数;它是在没有关键字参数的情况下调用函数,因此它在两个版本中都能正常工作。
与此同时,你说这很奇怪:
(major, minor, dummy1, dummy2, dummy3) = version_info
if major == 2 and minor == 7:
...但仅仅因为它过于冗长,而且取决于version_info
元组在此版本和所有未来版本中将始终具有5个组件的事实。这样做的惯用方法是:
if version_info >= (2, 7):
如果你不明白为什么会这样,请阅读Comparisons上的文档,然后在比较不同的元组之前进行比较。
然而,检查名称而不是检查版本甚至更好。只需try
,即可使用ImportError
和后备代码处理相关的NameError
或except
。 Mateo的答案显示了如何做到这一点:
try:
from syslog import syslog, openlog, LOG_PID
openlog('syslog', LOG_PID)
except ImportError:
from syslog import syslog
除此之外,这意味着您不必猜测或弄清楚添加了哪些版本,并冒着猜测错误的风险 - 就像您在这种情况下所做的那样。
下一步:
无论如何我还能在2.6中获得相同的功能吗?
当然,但不是使用stdlib syslog
模块。它不像2.6中的功能,但只是隐藏在用户之外,它不存在。
如果您search PyPI for syslog
,您会发现可以使用的各种第三方模块。
但如果您的平台syslog
没有LOG_PID
,那么您所做的任何事情都不会使syslog
接受该选项。
您可能希望将logging
与SysLogHandler
一起使用,并在 Python 级别而不是 syslog 级别配置它。< / p>
或者,您可以坚持使用syslog
并手动将pid粘贴到消息上 - 这是一个可怕的黑客攻击,但如果平台的syslog没有记录pids并且您拒绝使用任何内容,那么您还要做什么?但系统日志?
答案 1 :(得分:1)
我认为你可以尝试:除外。类似的东西:
try:
from syslog import openlog, LOG_PID
openlog(logoption=LOG_PID)
except ImportError:
from syslog import syslog
这使得它不具有特定版本。
完全披露:当我尝试做类似的事情时,我从Best way to import version-specific python modules得到了这个答案。