2013-07-18 16 views
2

Python中有没有一种方法可以检测进程内正在执行的进程?我有一些代码,其中包括getpass.getpass()函数,其中is broken in Spyder,并且它总是在命令行和IDE之间来回切换。检测Python代码在哪里运行(例如,在Spyder解释器与IDLE与CMD之间)

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

'sys.executable'有帮助吗? http://docs.python.org/2/library/sys.html#sys.executable –

+0

@DanLecocq这很有帮助。我会稍微处理一下,看看我能想出什么。 – Air

+0

我试过了,但问题是Spyder只是调用普通的python可执行文件。我注意到的一件事是它重写了sys.exit()调用,以便它不会终止您的解释器。有人知道如何利用它? – Markus

回答

4

这是我最终使用的解决方案。在阅读Markus's answer之后,我注意到Spyder增加了六个左右的环境变量到os.environ,其名称如SPYDER_ENCODING,SPYDER_SHELL_ID等。与检测不存在具有通用a的变量相比,这些中的任何一个似乎都是相对明确的名称为'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安装和一个单独的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安装文件夹的名字比,他们将重新命名其IDLE可执行,我的最终代码使用sys.executable来检测IDLE,并使用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: ") 
+1

我可以补充一点,这种方法也适用于PyCharme IDE,即简单地用“PYCHARM”替换“SPYDER”。 – emher

+0

如果用户在其环境中预定义了SPYDER_something,则会产生误报。 –

0

你可以添加环境变量在运行Spyder的时候,并检查它的代码:如果我能像添加代码这将是有益的。

2

默认情况下,Spyder使用启动脚本,请参阅首选项 - >控制台 - > Adanced设置。该选项通常设置为加载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。在我的机器上(使用Anaconda Python堆栈),它没有为普通的Python shell设置。你可以做

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

谢谢,这很有帮助。建议编辑以反映os.environ不可调用。 – Air

+0

此外,'globals()'只提供模块名称空间,因此在导入调用'getpass'的模块时,您的第一个建议将不起作用。 – Air

+0

啊,谢谢。删除了大括号。但是,必须考虑导入问题。 – Markus

1

Spyder提供了在本地系统终端中执行当前编辑器脚本的选项。这会产生相同的行为,就像从命令行运行一样。要设置它,请打开F6打开运行设置对话框。然后选择单选按钮“在外部系统终端中执行”。现在通过点击F5像往常一样运行脚本。您应该能够以这种方式以正常方式使用getpass

+1

您也可以在同一个“运行设置”对话框中启用“与执行后的Python解释器进行交互”,并且可以在代码运行后或在抛出错误之后保持解释器处于打开状态。 – Jed