在sitecustomize中检查Python交互模式

1 投票
3 回答
716 浏览
提问于 2025-04-16 20:57

我有一个类似于“每日一言”的消息,它会在启动解释器时显示。目前这个消息是在sitecustomize中打印的。如果解释器不是在交互模式下,我想要隐藏这个消息;但是不幸的是,所有在判断Python是否在交互模式下的检查在sitecustomize中都不管用。(sys.argvsys.ps1__main__.__file__这些都没有被填充。)有没有什么检查可以在sitecustomize中使用?

3 个回答

1

也许这个检查解释器是否可以交互使用的想法对你有帮助,它利用了 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 中设置这个变量指向你想要的文件,但我在查找加载顺序时又回到了我回答的第一部分的链接。

2

查看 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.
2

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),不过功能是可以实现的。

撰写回答