Python Vs C - Handling environment variable in Windows
I see a variation in output between C and python code in Windows trying to get t开发者_JAVA技巧he same functionality. The c code ( similar to unix shell scripts ) shows the TEST1 environment variable in 'test.bat.output' with its value as empty string whereas the python code removes this environment variable.
Is there a way to ask Python not to remove the environment variable from environ table when it is empty?
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
Cross-platform compatibility between Windows and "most everybody else" (operating systems derived or inspired from Unix) is often hard to get, especially in the innumerable corner cases that inevitably arise (e.g., as in this question, "does setting an environment variable to empty mean unsetting it"). Sometimes it's just easier to access Windows specific functionality directly rather than trying to stretch the "cross-platform" functionality.
While the traditional way to access Windows-specific functionality from Python is the win32all extension package, in recent Python versions the ctypes standard library module offers an alternative with the advantage of requiring no installation of C coded extensions. An interesting project is jaraco.windows, a set of pure-Python code on top of ctypes
to make Windows operations easier and smoother. For example, if you work with the environment and/or the registry, the environ.py module offers a nice set of functions and classes with a more Pythonic feel to them than the bare win32 API as accessed by the underlying ctypes
(e.g., get an exception with a readable error message in it in case of errors, rather than having to check return codes &c).
This is a possible answer. I don't have a Windows system handy to test with, so I don't really know what this code will do, but what happens if you do this:
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()
In my opinion, you might be encountering a Python bug of some kind. Especially if the code I just gave works.
Also, testing your code under Unix does work. The environment ends up with an empty environment variable in it.
Yes empty values are not being put into environ, but interesting thing is calling SetEnvironmentVariable from win32api or ctypes module has same affect as os.environ though win32api.SetEnvironmentVariable would be calling the same function as in C .
So are you sure you get different result in C code?
import win32api
import os
win32api.SetEnvironmentVariable("TEST1", "")
# or
# import ctypes
# ctypes.windll.kernel32.SetEnvironmentVariable("TEST1", "")
os.system("echo %TEST1%")
精彩评论