zoukankan      html  css  js  c++  java
  • Python AttributeError: 'Module' object has no attribute 'STARTF_USESHOWINDOW'

    夫学须志也,才须学也,非学无以广才,非志无以成学。——诸葛亮
    生活有度,自得慈铭 ——杜锦阳


    今天新来的同事安装环境遇到个莫名其妙的问题:
    AttributeError: 'Module' object has no attribute 'STARTF_USESHOWINDOW' 
    

    其它小伙伴好像都没遇到过,后来发现,应该是系统的问题,因为还出现了字节混乱的错误:
    UNICODEENCODEERROR:‘ascii’ code can't encode...

    这个先不提,我们先来看看下面的错误: STARTF_USESHOWINDOW

    深圳市米奇云科技有限公司

    因公司信息,所以打上马赛克了。

    百度了一会,发现网上解决方案都不靠谱。

    出错原因:使用了subprocess模块,系统找不到这个模块。

    你可以做个测试:在python下输出subprocess也会报这个错。

    后来想到有可能系统环境的问题和模块代码引起,起初是替换了Libsite-packagesmatplotlibcompat下的subprocess.py,后来想到这是子模块,于是再替换了Lib下的 subprocess.py ,再运行,一切正常。

    国内外论坛都没找到相关的解释,后来去翻了源码才知道了原因,Cmd是WIN下命令符,pyc是编译后运行的,和JAVA一样,一次编译多处运行,如果出现这个错误的小伙伴可以找这几个地方替换下,或者直接拿可运行版本的丢进去覆盖下。

    我们来翻看一下:

    if mswindows:
        import threading
        import msvcrt
        import _subprocess
        class STARTUPINFO:
            dwFlags = 0
            hStdInput = None
            hStdOutput = None
            hStdError = None
            wShowWindow = 0
        class pywintypes:
            error = IOError
    else:
        import select
        _has_poll = hasattr(select, 'poll')
        import fcntl
        import pickle
    
        # When select or poll has indicated that the file is writable,
        # we can write up to _PIPE_BUF bytes without risk of blocking.
        # POSIX defines PIPE_BUF as >= 512.
        _PIPE_BUF = getattr(select, 'PIPE_BUF', 512)
    

    此处是引入了 import _subprocess 模块,也就是说 subprocess.py -> _subprocess

    然后定位到:

    if mswindows:
            #
            # Windows methods
            #
    

    在这下面找到:

     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):
                """Execute program (MS Windows version)"""
    
                if not isinstance(args, types.StringTypes):
                    args = list2cmdline(args)
    
                # Process startup details
                if startupinfo is None:
                    startupinfo = STARTUPINFO()
                if None not in (p2cread, c2pwrite, errwrite):
                    startupinfo.dwFlags |= _subprocess.STARTF_USESTDHANDLES
                    startupinfo.hStdInput = p2cread
                    startupinfo.hStdOutput = c2pwrite
                    startupinfo.hStdError = errwrite
    
                if shell:
                    startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
                    startupinfo.wShowWindow = _subprocess.SW_HIDE
                    comspec = os.environ.get("COMSPEC", "cmd.exe")
                    args = '{} /c "{}"'.format (comspec, args)
                    if (_subprocess.GetVersion() >= 0x80000000 or
                            os.path.basename(comspec).lower() == "command.com"):
                        # Win9x, or using command.com on NT. We need to
                        # use the w9xpopen intermediate program. For more
                        # information, see KB Q150956
                        # (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)
                        # Not passing CREATE_NEW_CONSOLE has been known to
                        # cause random failures on win9x.  Specifically a
                        # dialog: "Your program accessed mem currently in
                        # use at xxx" and a hopeful warning about the
                        # stability of your system.  Cost is Ctrl+C wont
                        # kill children.
                        creationflags |= _subprocess.CREATE_NEW_CONSOLE
    

    看到这里,应该不难发现,CREATE_NEW_CONSOLE 是如何触发的。

    再来看下main方法的测试入口:

    """
      KARL-Dujinyang
      QQ:309933706
    """
    if __name__ == "__main__":
        if mswindows:
            _demo_windows()
        else:
            _demo_posix()
    

    mswindows 在我们文章开头代码中已经提及了,测试的可以拿到此处代码进行测试:

    mswindows = (sys.platform == "win32")
    

    _demo_windows 方法的定义:

    def _demo_windows():
        #
        # Example 1: Connecting several subprocesses
        #
        print "Looking for 'PROMPT' in set output..."
        p1 = Popen("set", stdout=PIPE, shell=True)
        p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)
        print repr(p2.communicate()[0])
    
        #dujinyang
        # Example 2: Simple execution of program
        #
        print "Executing calc..."
        p = Popen("calc")
        p.wait()
    

    可以看出,这里是由 OPEN->CLOSE 所引起的问题。如果出现这个错误的小伙伴可以找这几个地方替换下,或者直接拿可运行版本的丢进去覆盖下,也可以找我拿下源码覆盖,后面如果有时间我会上传到一份到CSDN上。


    || 版权声明:本文为博主杜锦阳原创文章,转载请注明出处。

    || 版权声明:本文为博主杜锦阳原创文章,转载请注明出处。


    作者:奥特曼超人Dujinyang

    来源:CSDN

    原文:https://dujinyang.blog.csdn.net/

    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    BZOJ2809 dispatching
    BZOJ1486 最小圈
    BZOJ1096 仓库建设
    BZOJ3190 赛车
    BZOJ1911 特别行动队
    BZOJ1202 狡猾的商人
    BZOJ1007 水平可见直线
    BZOJ2150 部落战争
    如何用PHP遍历文件数目 或删除目录下的全部文件?
    php对文件/目录操作的基础知识(图解)
  • 原文地址:https://www.cnblogs.com/python2048/p/11465815.html
Copyright © 2011-2022 走看看