在sitecustomize中检查Python交互模式
我有一个类似于“每日一言”的消息,它会在启动解释器时显示。目前这个消息是在sitecustomize中打印的。如果解释器不是在交互模式下,我想要隐藏这个消息;但是不幸的是,所有在判断Python是否在交互模式下的检查在sitecustomize中都不管用。(sys.argv
、sys.ps1
、__main__.__file__
这些都没有被填充。)有没有什么检查可以在sitecustomize中使用?
3 个回答
也许这个检查解释器是否可以交互使用的想法对你有帮助,它利用了 inspect
模块,并检查了堆栈帧:
http://mail.python.org/pipermail/pythonmac-sig/2002-February/005054.html
你也可以直接查看 pydoc.help()
的源代码,上面提到的代码片段就是受它启发的。
我刚意识到,你可以简单地利用一个包含你交互提示的文件,使用 PYTHONSTARTUP
环境变量。这个环境变量指向的文件中的命令,只有在解释器以交互模式运行时才会被执行。
http://docs.python.org/tutorial/interpreter.html#the-interactive-startup-file
如果你不想在 Python 外部设置这个环境变量,你可以尝试在 sitecustomize.py
中设置这个变量指向你想要的文件,但我在查找加载顺序时又回到了我回答的第一部分的链接。
查看 sys.flags 是一种更简洁的方法。
>>> import sys
>>> sys.flags.interactive
1
需要注意的是,IDLE 本身也是一种交互式的环境,但它并没有设置这个标志。我会这样做:
>>> if sys.flags.interactive or sys.modules.has_key('idlelib'):
>>> pass # do stuff specific to interactive.
JAB让我开始关注这段代码,最后我想出了这个:
import ctypes
import getopt
ctypes.pythonapi.Py_GetArgcArgv.restype = None
ctypes.pythonapi.Py_GetArgcArgv.argtypes = [
ctypes.POINTER(ctypes.c_int),
ctypes.POINTER(ctypes.POINTER(ctypes.c_char_p))]
count = ctypes.c_int()
args = ctypes.pointer(ctypes.c_char_p())
ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(count), ctypes.byref(args))
argc = count.value
argv = [args[i] for i in range(count.value)]
if argc > 1:
interactive = False
opts, args = getopt.getopt(argv[1:], 'i')
for o, a in opts:
if o == '-i':
interactive = True
else:
interactive = True
这段代码看起来有点丑(而且对于Python 3来说,c_char_p需要改成c_wchar_p),不过功能是可以实现的。