Python与C - 在Windows中处理环境变量
我发现,在Windows系统中,C语言和Python代码的输出结果有些不同,虽然它们想实现相同的功能。C语言的代码(类似于Unix的脚本)在'test.bat.output'文件中显示了TEST1这个环境变量,但它的值是空字符串。而Python的代码则把这个环境变量给删掉了。
有没有办法让Python在环境变量为空的时候,不把它从环境表中删除呢?
C
#include <windows.h>
main()
{
DWORD dwRet;
char pszOldVal[1024] = "abc";
if(! SetEnvironmentVariable("TEST1", ""))
puts("Error\n");
// _putenv("TEST1=");
// GetEnvironmentVariable("TEST1", pszOldVal, dwRet);
system("cmd /c test.bat >test.bat.output");
}
Python
import os
os.environ['TEST1'] = ""
os.environ['TEST2'] = "karthik"
os.system("cmd /c test.bat > test.bat.output.python")
-Karthik
3 个回答
是的,空值不会被放入环境变量中。不过有趣的是,从win32api或ctypes模块调用SetEnvironmentVariable的效果和os.environ是一样的,尽管win32api.SetEnvironmentVariable实际上调用的是和C语言中相同的函数。
那么,你确定在C代码中得到的结果是不同的吗?
import win32api
import os
win32api.SetEnvironmentVariable("TEST1", "")
# or
# import ctypes
# ctypes.windll.kernel32.SetEnvironmentVariable("TEST1", "")
os.system("echo %TEST1%")
在Windows和其他大多数操作系统(那些源自或受到Unix启发的系统)之间,想要实现跨平台兼容性常常很困难,尤其是在那些不可避免的小问题上(比如这个问题:“把环境变量设置为空,是否意味着取消设置?”)。有时候,直接使用Windows特有的功能会比试图让“跨平台”功能适应更简单。
传统上,从Python访问Windows特有功能的方式是使用win32all扩展包,但在最近的Python版本中,ctypes这个标准库模块提供了一个替代方案,它的好处是无需安装C语言编写的扩展。一个有趣的项目是jaraco.windows,这是一个基于ctypes
的纯Python代码集合,旨在让Windows操作变得更简单、更顺畅。例如,如果你需要处理环境变量或注册表,environ.py模块提供了一组功能和类,它们比直接使用底层ctypes
访问的win32 API更符合Python的风格(比如在出错时能得到可读的错误信息,而不是只检查返回码等)。
这是一个可能的回答。我手头没有Windows系统可以测试,所以我不太清楚这段代码会有什么效果,但如果你这样做,会发生什么呢:
import os, subprocess
myenv = {}
myenv.update(os.environ)
myenv['TEST1'] = ""
myenv['TEST2'] = "karthik"
subprocess.Popen(('cmd', '/c', 'test.bat'), stdout=file("test.bat.output.python", 'w'),
env=myenv).wait()
在我看来,你可能遇到了某种Python的bug。特别是如果我刚给你的代码能够正常工作的话。
另外,在Unix系统下测试你的代码是可以的。最终的环境变量会是一个空的状态。