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

检测Python代码运行的位置(例如,在Spyder解释器与IDLE与cmd中),python,interpreter,spyder,Python,Interpreter,Spyder,Python中是否有一种方法可以在进程内检测该进程的执行位置?我有一些代码,其中包括getpass.getpass()函数,它一直在命令行和IDE之间来回运行,这很烦人。如果我可以添加如下代码,这将非常有用: if not being run from Spyder: use getpass else: use alternative 您可以在Spyder中运行时添加env变量并在代码中签入它。默认情况下,Spyder使用启动脚本,请参阅“首选项->控制台->高级设置”。此选项

Python中是否有一种方法可以在进程内检测该进程的执行位置?我有一些代码,其中包括
getpass.getpass()
函数,它一直在命令行和IDE之间来回运行,这很烦人。如果我可以添加如下代码,这将非常有用:

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

您可以在Spyder中运行时添加env变量并在代码中签入它。

默认情况下,Spyder使用启动脚本,请参阅“首选项->控制台->高级设置”。此选项通常设置为加载pylab等人的
scientific_startup.py
文件

最简单的解决方案是向文件中添加一个全局变量,然后在if语句中使用它,例如,在
scientific_startup.py
的末尾添加这一行:

SPYDER_IDE_ACTIVE = True
在脚本中:

if not 'SPYDER_IDE_ACTIVE' in globals():
    use getpass
else:
    use alternative
这将在不抛出错误的情况下工作。如果您更喜欢,也可以使用异常

第二种解决方案是(如果由于某种原因无法修改该文件),只需检查是否设置了环境变量
PYTHONSTARTUP
。在我的机器上(使用anacondapython堆栈),它不是为常规pythonshell设置的。你可以

import os
if not 'PYTHONSTARTUP' in os.environ:
    use getpass
else:
    use alternative

这是我最终使用的解决方案。阅读后,我注意到Spyder向
os.environ
添加了六个左右的环境变量,其名称如
Spyder\u ENCODING
Spyder\u SHELL\u ID
,等等。检测这些变量的存在似乎比较明确,与检测缺少一个名为
'PYTHONSTARTUP'
的通用变量相比。代码很简单,独立于Spyder的启动脚本(据我所知):

由于字符串位于每个环境变量名称的开头,您也可以使用
str.startswith
,但它灵活性较低,速度稍慢(我很好奇):

根据您的安装情况,
sys.executable
方法可能有用,也可能无效。我有两个WinPython安装和一个单独的Python 2.7安装,因此我能够检查条件
sys.executable.find('WinPy')==-1
,以检测Spyder使用的可执行文件路径中的文件夹名称。由于当您尝试使用
getpass
时,在IDLE中显示的警告比它可能发出的声音要小,因此在我看来,我最后还检查了条件
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\n\n' * 3
                         + 'Please enter your password: ')
else:        
    password = getpass.getpass("Please enter your password: ")

Spyder提供了在本机系统终端中执行当前编辑器脚本的选项。这将产生与从命令行运行相同的行为。要设置此设置,请通过点击
F6
打开“运行设置”对话框。然后选择单选按钮“在外部系统终端中执行”。现在通过点击
F5
像往常一样运行脚本。通过这种方法,您应该能够以正常方式使用
getpass
sys.executable
对您有帮助吗@DanLecocq,这很有帮助。我会稍微研究一下,看看我能想出什么。我试过了,但问题是Spyder只调用普通的python可执行文件。我注意到的一点是,它重写sys.exit()调用,这样就不会杀死解释器。有人知道如何利用它吗?谢谢,这很有帮助。建议编辑以反映os.environ不可调用。此外,
globals()
只提供模块名称空间,因此在导入调用
getpass
的模块时,您的第一个建议将不起作用。啊,谢谢。拆下支架。但是,必须考虑导入的问题。您还可以从同一个运行设置对话框启用“执行后与Python解释器交互”,这将在代码运行后或抛出错误后保持解释器打开。我可以补充,这种方法也适用于PyCharme IDE,即简单地将“SPYDER”替换为“PYCHARM”。如果用户在其环境中有预定义的SPYDER_内容,则会给出误报。
if sys.executable.find('pythonw.exe') == sys.executable.find('WinPy') == -1:
    # use getpass
else:        
    # use alternative
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\n\n' * 3
                         + 'Please enter your password: ')
else:        
    password = getpass.getpass("Please enter your password: ")