检测Python代码在哪里运行(例如,在Spyder解释器与IDLE与cmd中)

2022-04-05 00:00:00 python spyder interpreter

问题描述

在Python中有没有一种方法可以在进程中检测到该进程正在执行的位置?我有一些代码包含getpass.getpass()函数,其中is broken in Spyder,总是在命令行和IDE之间来回切换是很烦人的。如果我可以添加如下代码将非常有用:

if not being run from Spyder:
    use getpass
else:
    use alternative

解决方案

这是我最终使用的解决方案。在阅读Markus's answer后,我注意到Spyder向os.environ添加了六个左右的环境变量,其名称类似于SPYDER_ENCODINGSPYDER_SHELL_ID等。与检测不存在具有'PYTHONSTARTUP'这样通用名称的变量相比,检测这些变量的存在似乎相对明确。代码很简单,并且独立于Spyder的启动脚本工作(据我所知):

if any('SPYDER' in name for name in os.environ)
    # use alternative
else:        
    # use getpass

因为字符串位于每个环境变量名的开头,所以您也可以使用str.startswith,但它不太灵活,而且速度稍慢(我很好奇):

>>> import timeit
>>> s = timeit.Timer("[name.startswith('SPYDER') for name in os.environ]", "import os")
>>> i = timeit.Timer("['SPYDER' in name for name in os.environ]", "import os")
>>> s.timeit()
16.18333065883474
>>> i.timeit()
6.156869294143846
sys.executable方法可能有用,也可能不有用,具体取决于您的安装。我有两个WinPython安装和一个单独的Python2.7安装,所以我能够检查sys.executable.find('WinPy') == -1条件以检测Spyder使用的可执行文件路径中的文件夹名。由于当您尝试使用getpass时显示的空闲警告没有那么"响亮",在我看来,我最后还检查了sys.executable.find('pythonw.exe') == -1条件以使其稍微响亮一些。仅使用sys.executable,该方法如下所示:

if sys.executable.find('pythonw.exe') == sys.executable.find('WinPy') == -1:
    # use getpass
else:        
    # use alternative

但由于我希望这在其他计算机上运行,并且其他用户更有可能修改他们的WinPython安装文件夹名,而不是重命名他们空闲的可执行文件,所以我的最终代码使用sys.executable检测空闲,os.environ检测Spyder,在这两种情况下都会提供更响亮的警告,并防止代码在后一种情况下中断。

if any('SPYDER' in name for name in os.environ) 
   or 'pythonw.exe' in sys.executable:
    password = raw_input('WARNING: PASSWORD WILL BE SHOWN ON SCREEN

' * 3
                         + 'Please enter your password: ')
else:        
    password = getpass.getpass("Please enter your password: ")

相关文章