检测Python代码在何处运行(例如,在Spyder解释器、IDLE和cmd中)

时间:2022-04-04 20:46:38

Is there a way in Python to detect, within a process, where that process is being executed? I have some code that includes the getpass.getpass() function, which is broken in Spyder, and it's annoying to go back and forth between the command line and the IDE all the time. It would be useful if I could add code like:

在Python中,是否存在一种方法来检测进程在何处执行?我有一些包含getpass.getpass()函数的代码,它在Spyder中被破坏了,在命令行和IDE之间来回切换很烦人。如果我能增加如下代码将会很有用:

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

4 个解决方案

#1


4  

Here is the solution I ended up using. After reading Markus's answer, I noticed that Spyder adds half a dozen or so environment variables to os.environ with names like SPYDER_ENCODING, SPYDER_SHELL_ID, etc. Detecting the presence of any of these seems relatively unambiguous, compared to detecting the absence of a variable with as generic a name as 'PYTHONSTARTUP'. The code is simple, and works independently of Spyder's startup script (as far as I can tell):

这是我最后使用的解决方案。在阅读了Markus的答案之后,我注意到Spyder向os添加了大约6个环境变量。与SPYDER_ENCODING、SPYDER_SHELL_ID等名称的环境相比,检测这些名称的存在似乎比较明确,相比之下,如果没有一个变量的名称为“PYTHONSTARTUP”,那么这个变量就不存在了。代码很简单,独立于Spyder的启动脚本(据我所知):

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

Since the string is at the beginning of each environment variable name, you could also use str.startswith, but it's less flexible, and a little bit slower (I was curious):

由于字符串位于每个环境变量名称的开头,您也可以使用string .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

The sys.executable method may or may not be useful depending on your installation. I have a couple WinPython installations and a separate Python 2.7 installation, so I was able to check the condition sys.executable.find('WinPy') == -1 to detect a folder name in the path of the executable Spyder uses. Since the warning that shows in IDLE when you try to use getpass is less "loud" than it could be, in my opinion, I ended up also checking the condition sys.executable.find('pythonw.exe') == -1 to make it slightly louder. Using sys.executable only, that method looks like:

sys。可执行方法可能有用,也可能没有用,这取决于您的安装。我有两个WinPython安装和一个单独的Python 2.7安装,因此我可以检查条件系统.executable.find('WinPy') = -1,以检测可执行Spyder使用路径中的文件夹名。由于当您尝试使用getpass时,提示为IDLE的警告的“音量”比可能的要小,因此在我看来,我最后还检查了条件系统.executable.find('pythonw.exe') = -1以使它稍微大一些。使用系统。仅可执行,该方法看起来如下:

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

But since I want this to work on other machines, and it's much more likely that another user would modify their WinPython installation folder name than that they would rename their IDLE executable, my final code uses sys.executable to detect IDLE and os.environ to detect Spyder, providing a "louder" warning in either case and keeping the code from breaking in the latter.

但是由于我想让它在其他机器上工作,而且很有可能另一个用户会修改他们的WinPython安装文件夹名称,而不是重命名他们的空闲可执行文件,所以我的最终代码使用sys。可执行文件以检测空闲和操作系统。检测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: ")

#2


2  

By default, Spyder uses a startup scrip, see Preferences -> Console -> Adanced setting. This option is usually set to the scientific_startup.py file that loads pylab et al.

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

The easiest solution is to just add a global variable to the file and then use that in your if statement, e.g. add this line at the end of scientific_startup.py:

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

SPYDER_IDE_ACTIVE = True

In your script:

在你的脚本:

if not 'SPYDER_IDE_ACTIVE' in globals():
    use getpass
else:
    use alternative

This will work without throwing an error. You can also use exceptions if you like that more.

这将不会抛出错误。如果您更喜欢异常,也可以使用异常。

A second solution would be (if you cannot modify that file for some reason) to just check if the environment variable PYTHONSTARTUP is set. On my machine (using the Anaconda Python stack), it is not set for a regular Python shell. You could do

第二种解决方案是(如果由于某种原因不能修改该文件)检查环境变量PYTHONSTARTUP是否设置好了。你可以做

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

#3


1  

Spyder provides the option of executing the current editor script in a native system terminal. This would produce identical behavior as if you were running from the command line. To set this up, open the Run Settings dialog by hitting F6. Then select the radio button "Execute in an external System terminal". Now run the script as usual by hitting F5. You should be able to use getpass in the normal fashion with this approach.

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

#4


0  

You could add env variable when running in Spyder and check it in code.

在Spyder中运行时,您可以添加env变量,并在代码中检查它。

#1


4  

Here is the solution I ended up using. After reading Markus's answer, I noticed that Spyder adds half a dozen or so environment variables to os.environ with names like SPYDER_ENCODING, SPYDER_SHELL_ID, etc. Detecting the presence of any of these seems relatively unambiguous, compared to detecting the absence of a variable with as generic a name as 'PYTHONSTARTUP'. The code is simple, and works independently of Spyder's startup script (as far as I can tell):

这是我最后使用的解决方案。在阅读了Markus的答案之后,我注意到Spyder向os添加了大约6个环境变量。与SPYDER_ENCODING、SPYDER_SHELL_ID等名称的环境相比,检测这些名称的存在似乎比较明确,相比之下,如果没有一个变量的名称为“PYTHONSTARTUP”,那么这个变量就不存在了。代码很简单,独立于Spyder的启动脚本(据我所知):

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

Since the string is at the beginning of each environment variable name, you could also use str.startswith, but it's less flexible, and a little bit slower (I was curious):

由于字符串位于每个环境变量名称的开头,您也可以使用string .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

The sys.executable method may or may not be useful depending on your installation. I have a couple WinPython installations and a separate Python 2.7 installation, so I was able to check the condition sys.executable.find('WinPy') == -1 to detect a folder name in the path of the executable Spyder uses. Since the warning that shows in IDLE when you try to use getpass is less "loud" than it could be, in my opinion, I ended up also checking the condition sys.executable.find('pythonw.exe') == -1 to make it slightly louder. Using sys.executable only, that method looks like:

sys。可执行方法可能有用,也可能没有用,这取决于您的安装。我有两个WinPython安装和一个单独的Python 2.7安装,因此我可以检查条件系统.executable.find('WinPy') = -1,以检测可执行Spyder使用路径中的文件夹名。由于当您尝试使用getpass时,提示为IDLE的警告的“音量”比可能的要小,因此在我看来,我最后还检查了条件系统.executable.find('pythonw.exe') = -1以使它稍微大一些。使用系统。仅可执行,该方法看起来如下:

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

But since I want this to work on other machines, and it's much more likely that another user would modify their WinPython installation folder name than that they would rename their IDLE executable, my final code uses sys.executable to detect IDLE and os.environ to detect Spyder, providing a "louder" warning in either case and keeping the code from breaking in the latter.

但是由于我想让它在其他机器上工作,而且很有可能另一个用户会修改他们的WinPython安装文件夹名称,而不是重命名他们的空闲可执行文件,所以我的最终代码使用sys。可执行文件以检测空闲和操作系统。检测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: ")

#2


2  

By default, Spyder uses a startup scrip, see Preferences -> Console -> Adanced setting. This option is usually set to the scientific_startup.py file that loads pylab et al.

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

The easiest solution is to just add a global variable to the file and then use that in your if statement, e.g. add this line at the end of scientific_startup.py:

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

SPYDER_IDE_ACTIVE = True

In your script:

在你的脚本:

if not 'SPYDER_IDE_ACTIVE' in globals():
    use getpass
else:
    use alternative

This will work without throwing an error. You can also use exceptions if you like that more.

这将不会抛出错误。如果您更喜欢异常,也可以使用异常。

A second solution would be (if you cannot modify that file for some reason) to just check if the environment variable PYTHONSTARTUP is set. On my machine (using the Anaconda Python stack), it is not set for a regular Python shell. You could do

第二种解决方案是(如果由于某种原因不能修改该文件)检查环境变量PYTHONSTARTUP是否设置好了。你可以做

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

#3


1  

Spyder provides the option of executing the current editor script in a native system terminal. This would produce identical behavior as if you were running from the command line. To set this up, open the Run Settings dialog by hitting F6. Then select the radio button "Execute in an external System terminal". Now run the script as usual by hitting F5. You should be able to use getpass in the normal fashion with this approach.

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

#4


0  

You could add env variable when running in Spyder and check it in code.

在Spyder中运行时,您可以添加env变量,并在代码中检查它。