解決:pipenv shell報錯:AttributeError: 'module' object has no attribute 'run'

利用pipenv shell切換到虛擬環境時,顯示報錯:AttributeError: 'module' object has no attribute 'run'html

能夠看到是d:\program\python34\lib\site-packages\pipenv\shells.py文件的第62行報錯了,提示模塊沒有run的屬性,因而就跑到該文件的第62行去看python

選中run,CTRL+B發現能看到源碼,源碼以下:shell

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函數多了下面兩行session

         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方法)ui

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)spa

再次使用pipenv shell,發現能夠切換到虛擬環境了rest

 

 

 

參考文章

https://cuiqingcai.com/5846.htmlcode

相關文章
相關標籤/搜索