zoukankan      html  css  js  c++  java
  • 解决:pipenv shell报错:AttributeError: 'module' object has no attribute 'run'

    利用pipenv shell切换到虚拟环境时,显示报错:AttributeError: 'module' object has no attribute 'run'

    可以看到是d:programpython34libsite-packagespipenvshells.py文件的第62行报错了,提示模块没有run的属性,于是就跑到该文件的第62行去看

    选中run,CTRL+B发现能看到源码,源码如下:

    if sys.version_info >= (3, 6):
            # Nearly same args as Popen.__init__ except for timeout, input, and check
            def run(args: _CMD,
                    timeout: Optional[float] = ...,
                    input: Optional[_TXT] = ...,
                    check: bool = ...,
                    bufsize: int = ...,
                    executable: _PATH = ...,
                    stdin: _FILE = ...,
                    stdout: _FILE = ...,
                    stderr: _FILE = ...,
                    preexec_fn: Callable[[], Any] = ...,
                    close_fds: bool = ...,
                    shell: bool = ...,
                    cwd: Optional[_PATH] = ...,
                    env: Optional[_ENV] = ...,
                    universal_newlines: bool = ...,
                    startupinfo: Any = ...,
                    creationflags: int = ...,
                    restore_signals: bool = ...,
                    start_new_session: bool = ...,
                    pass_fds: Any = ...,
                    *,
                    encoding: Optional[str] = ...,
                    errors: Optional[str] = ...) -> CompletedProcess: ...
        else:
            # Nearly same args as Popen.__init__ except for timeout, input, and check
            def run(args: _CMD,
                    timeout: Optional[float] = ...,
                    input: Optional[_TXT] = ...,
                    check: bool = ...,
                    bufsize: int = ...,
                    executable: _PATH = ...,
                    stdin: _FILE = ...,
                    stdout: _FILE = ...,
                    stderr: _FILE = ...,
                    preexec_fn: Callable[[], Any] = ...,
                    close_fds: bool = ...,
                    shell: bool = ...,
                    cwd: Optional[_PATH] = ...,
                    env: Optional[_ENV] = ...,
                    universal_newlines: bool = ...,
                    startupinfo: Any = ...,
                    creationflags: int = ...,
                    restore_signals: bool = ...,
                    start_new_session: bool = ...,
                    pass_fds: Any = ...) -> CompletedProcess: ...

    但是请看第一行 if sys.version_info >= (3, 6):  ,我们姑且猜测一下,这个3.6就是python的版本号,如果版本大于3.6,就用第一个run函数,否则就用第二个run函数,这两个函数有什么不同——第一个run函数多了下面两行

             encoding: Optional[str] = ...,
                   errors: Optional[str] = ...)

    可是,既然版本大于3.6和小于3.6都会调用已存在的run函数,那为什么会报错?我们来看一下比较完整的代码

    不知道有没有留意到当版本大于3.5时,才会去第二个if里判断是否大于3.6,而我当前的版本是3.4.4,因此不满足大于3.5的if判断,而满足大于3.3的if判断,此时下面的方法都是call了(事实上,只要满足版本<3.5,都应该调用的是call方法)

    if sys.version_info >= (3, 5):
        class CompletedProcess:
            # morally: _CMD
            args = ...  # type: Any
            returncode = ...  # type: int
            # morally: Optional[_TXT]
            stdout = ...  # type: Any
            stderr = ...  # type: Any
            def __init__(self, args: _CMD,
                         returncode: int,
                         stdout: Optional[_TXT] = ...,
                         stderr: Optional[_TXT] = ...) -> None: ...
            def check_returncode(self) -> None: ...
    
        if sys.version_info >= (3, 6):
            # Nearly same args as Popen.__init__ except for timeout, input, and check
            def run(args: _CMD,
                    timeout: Optional[float] = ...,
                    input: Optional[_TXT] = ...,
                    check: bool = ...,
                    bufsize: int = ...,
                    executable: _PATH = ...,
                    stdin: _FILE = ...,
                    stdout: _FILE = ...,
                    stderr: _FILE = ...,
                    preexec_fn: Callable[[], Any] = ...,
                    close_fds: bool = ...,
                    shell: bool = ...,
                    cwd: Optional[_PATH] = ...,
                    env: Optional[_ENV] = ...,
                    universal_newlines: bool = ...,
                    startupinfo: Any = ...,
                    creationflags: int = ...,
                    restore_signals: bool = ...,
                    start_new_session: bool = ...,
                    pass_fds: Any = ...,
                    *,
                    encoding: Optional[str] = ...,
                    errors: Optional[str] = ...) -> CompletedProcess: ...
        else:
            # Nearly same args as Popen.__init__ except for timeout, input, and check
            def run(args: _CMD,
                    timeout: Optional[float] = ...,
                    input: Optional[_TXT] = ...,
                    check: bool = ...,
                    bufsize: int = ...,
                    executable: _PATH = ...,
                    stdin: _FILE = ...,
                    stdout: _FILE = ...,
                    stderr: _FILE = ...,
                    preexec_fn: Callable[[], Any] = ...,
                    close_fds: bool = ...,
                    shell: bool = ...,
                    cwd: Optional[_PATH] = ...,
                    env: Optional[_ENV] = ...,
                    universal_newlines: bool = ...,
                    startupinfo: Any = ...,
                    creationflags: int = ...,
                    restore_signals: bool = ...,
                    start_new_session: bool = ...,
                    pass_fds: Any = ...) -> CompletedProcess: ...
    
    # Same args as Popen.__init__
    if sys.version_info >= (3, 3):
        # 3.3 added timeout
        def call(args: _CMD,
                 bufsize: int = ...,
                 executable: _PATH = ...,
                 stdin: _FILE = ...,
                 stdout: _FILE = ...,
                 stderr: _FILE = ...,
                 preexec_fn: Callable[[], Any] = ...,
                 close_fds: bool = ...,
                 shell: bool = ...,
                 cwd: Optional[_PATH] = ...,
                 env: Optional[_ENV] = ...,
                 universal_newlines: bool = ...,
                 startupinfo: Any = ...,
                 creationflags: int = ...,
                 restore_signals: bool = ...,
                 start_new_session: bool = ...,
                 pass_fds: Any = ...,
                 timeout: float = ...) -> int: ...
    else:
        def call(args: _CMD,
                 bufsize: int = ...,
                 executable: _PATH = ...,
                 stdin: _FILE = ...,
                 stdout: _FILE = ...,
                 stderr: _FILE = ...,
                 preexec_fn: Callable[[], Any] = ...,
                 close_fds: bool = ...,
                 shell: bool = ...,
                 cwd: Optional[_PATH] = ...,
                 env: Optional[_ENV] = ...,
                 universal_newlines: bool = ...,
                 startupinfo: Any = ...,
                 creationflags: int = ...,
                 restore_signals: bool = ...,
                 start_new_session: bool = ...,
                 pass_fds: Any = ...) -> int: ...
    

    了解这个,就知道如何解决了,只要修改源码把run换成call即可(如果要使用3.5及以上的版本,建议把call再换回run)

    再次使用pipenv shell,发现可以切换到虚拟环境了

    参考文章

    https://cuiqingcai.com/5846.html

  • 相关阅读:
    面向安全需求的VANET信道拥塞联合控制框架
    多普勒频移
    5G-Enabled Cooperative Intelligent Vehicular (5GenCIV) Framework: When Benz Meets Marconi
    Vehicle-to-Vehicle Channel Modeling and Measurements: Recent Advances and Future Challenges
    python之对象
    python之数字类型
    python之序列
    数据库进阶
    python之coding style
    python之web开发(待续)
  • 原文地址:https://www.cnblogs.com/my_captain/p/9589200.html
Copyright © 2011-2022 走看看