2013-11-21 69 views
0

我有一些代碼應該使用syslog記錄錯誤。登錄到系統日誌時,我希望腳本名稱和PID顯示在日誌本身中。從同一個庫導入兩次pluss版本問題

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

你至少在這裏問問題。問一個具體的問題要好得多。如果您需要提出多個問題,請將其作爲單獨的問題提出。 – abarnert

+0

你從哪裏得到「python 2.6不支持openlog,logoption和LOG_PID」的想法? – abarnert

+0

我進入了Python [文檔](http:// docs。python.org/2.6/library/syslog.html)爲2.6,並不能虛構它。另外,當試圖從syslog導入openlog和LOG_PID時,會引發錯誤。 – Mogget

回答

3

第一:

來自同一庫導入兩次

我不知道你怎麼想的問題是這一點,因爲你從來沒有在它是什麼甚至暗示。如果多次導入庫,庫實際上只導入一次,但每次都會發生作爲導入的一部分發生的任何名稱綁定。

「but」通常不是問題,但如果您嘗試使用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_PIDHere 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接受。但是這種差異不可能導致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,並使用except和後備代碼處理相關的ImportErrorNameError。刁的回答顯示瞭如何做到這一點:

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接受該選項。

您可能需要使用loggingSysLogHandler,並在的Python水平而不是在日誌級別配置。

或者,你可以用syslog堅持和粘性的PID到消息手動一個可怕的黑客,但還有什麼你打算如果平臺的系統日誌不記錄的PID做,你拒絕使用任何東西,但系統日誌?

1

我認爲你可以用try來做:除了。例如:

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得到了這個答案。

+0

他也想在第一種情況下導入'syslog',所以你想在第一行添加',syslog'但是否則,是的,如果這是你想要做的,這是Pythonic的方式。 – abarnert