夫有志要学,才要学。不学则不能广才,无志则不能学。——诸葛亮生活中庸,以仁厚为荣——杜今阳的新同事今天在安装环境遇到一个莫名其妙的问题:AttributeError:'Module'objecthasnoattribute'STARTF_USESHOWINDOW'其他朋友好像没遇到过它之前。发现应该是系统问题,因为还有一个字节混淆错误:UNICODEENCODEERROR:'ascii'codecan'tencode...先不说这个,再看下面的错误:STARTF_USESHOWINDOW由于公司原因资料,所以打上马赛克。百度了一会,发现网上的解决方案都不靠谱。错误原因:使用了subprocess模块??,但系统找不到该模块。大家可以做个测试:python下的outputsubprocess也会报这个错。后来想到可能是系统环境和模块代码有问题。一开始,我替换了Lib\site-packages\matplotlib\compat下的subprocess.py。后来觉得是子模块,就把lib下的subprocess.py换掉了。再次运行,一切正常。在国内外论坛上没有找到相关的解释。看了源码才知道原因。cmd是WIN下的命令字符,pyc编译运行。和JAVA一样,多处同时编译运行。如果出现这个错误小伙伴们可以找这些地方替换,或者直接把runnable版本丢进去覆盖。我们来看一下:ifmswindows:importthreadingimportmsvcrtimport_subprocessclassSTARTUPINFO:dwFlags=0hStdInput=NonehStdOutput=NonehStdError=NonewShowWindow=0classpywintypes:error=IOErrorelse:importpollelselect=_has_poll('')importfcntlimportpickle#当select或poll指示文件可写时,#我们可以写入_PIPE_BUF字节而不会有阻塞的风险。#POSIX定义PIPE_BUF为>=512。_PIPE_BUF=getattr(select,'PIPE_BUF',512)这里引入了import_subprocess模块,也就是说subprocess.py->_subprocess然后定位:ifmswindows:##Windows方法#Foundhere:def_execute_child(self,args,executable,preexec_fn,close_fds,cwd,env,universal_newlines,startupinfo,creationflags,shell,to_close,p2cread,p2cwrite,c2pread,c2pwrite,errread,errwrite):"""Executeprogram(MSWindowsversion)"""ifnotisinstance(args,types.StringTypes):args=list2cmdline(args)#如果startupinfo为None,处理启动细节:startupinfo=STARTUPINFO()ifNonenotin(p2cread,c2pwrite,errwrite):startupinfo.dwFlags|=_subprocess.STARTF_USESTDHANDLESstartupinfo.hStdInput=p2creadstartupinfo.hStdOutput=c2pwritestartupinfo.hStdError=errwriteifshell:startupinfo.dwFlags|=_subprocess.STARTF_USESHOWWINDOWstartupinfo.wShowWindow=_subprocess.SW_HIDEcomspec=os.environ.get("COMSPEC","cmd.exe")args='{}/c"{}"'.format(comspec,args)if(_subprocess.GetVersion()>=0x80000000或os.path.basename(comspec).lower()=="command.com"):#Win9x,或在NT上使用command.com。我们需要#使用w9xpopen中间程序。有关更多信息,请参阅KBQ150956#(http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)w9xpopen=self._find_w9xpopen()args='"%s"%s'%(w9xpopen,args)#已知不传递CREATE_NEW_CONSOLE会导致win9x随机失败。特别是一个#对话框:“你的程序访问了当前在#useatxxx中的内存”和一个关于你系统的#稳定性的充满希望的警告。成本是Ctrl+C不会#killchildren。creationflags|=_subprocess.CREATE_NEW_CONSOLE看这里,应该不难发现,CREATE_NEW_CONSOLE是怎么触发的我们看一下main方法的测试入口:"""KARL-都晋洋QQ:309933706"""if__name__=="__main__":ifmswindows:_demo_windows()else:_demo_posix()mswindows开头我们文章的代码中已经提到了,可以在这里获取代码进行测试:mswindows=(sys.platform=="win32")_demo_windows方法定义:def_demo_windows():##示例1:连接多个子进程#打印“在设置输出中寻找‘PROMPT’……”)printrepr(p2.communicate()[0])##例子2:程序的简单执行#print"Executingcalc..."p=Popen("calc")p.wait()可以看出这里是OPEN->CLOSE引起的问题。如果有这个报错,可以找这几个地方替换,或者直接丢runnable版本覆盖,也可以找我获取源码覆盖率,以后有时间我会上传一份到CSDN。版权声明:本文为博主杜金洋原创文章,转载请注明出处。作者:奥特曼超人杜金洋来源:CSDN原文:https://dujinyang.blog.csdn.net/版权声明:本文为博主原创文章,转载请附上博文链接!
