Подпроцесс python3: «ImportError: невозможно импортировать имя main» в терминале - PullRequest
0 голосов
/ 10 ноября 2018

Я создал скрипт (см. Ниже), чтобы обновить все мои pip-пакеты. Я успешно выполнил свой сценарий с помощью idle3, т.е. открыл сценарий с помощью idle3 и нажал F5, чтобы запустить сценарий как модуль. Однако я не могу выполнить его в терминале; получил ошибку ниже. Как мне преодолеть эту ошибку? Почему ошибка импорта происходит в терминале, а не в idle3?

$ python3 -m upgrade_pip_packages 
====================================================
UPGRADING ALL --USER PIP PACKAGES TO LATEST VERSION:
====================================================
Traceback (most recent call last):
  File "/usr/bin/pip", line 9, in <module>
    from pip import main
ImportError: cannot import name main
ERROR: Command 'pip list' returned non-zero exit status 1

Мой скрипт: upgrade_pip_packages.py

#!/bin/python3
import subprocess
from pprint import pprint


def get_pkgs():
    try:
        cmd = 'pip list'
        completed = subprocess.run( cmd, shell=True, check=True,
                                    stdout=subprocess.PIPE )
    except subprocess.CalledProcessError as err:
        print( 'ERROR:', err )
    else:
        for line in completed.stdout.decode('utf-8').splitlines()[2:]:
            yield line


def update_pkgs(piplist):
    npackages = 0
    nupgrades = 0
    nerrors = 0
    upgradelist = []
    errorlist = []
    for i in piplist:
        npackages += 1
        pkgname, ver = i.split()
        print('\n',pkgname)
        try:
            cmd = 'pip install --user {} --upgrade'.format(pkgname)
            completed = subprocess.run( cmd, shell=True, check=True,
                                        stdout=subprocess.PIPE )
        except subprocess.CalledProcessError as err:
            nerrors += 1
            errorlist.append(pkgname)
            print( 'ERROR: {}'.format(err) )
        else:
            for line in completed.stdout.decode('utf-8').splitlines():
                print(line)
                if 'Successfully installed' in line:
                    nupgrades +=1
                    upgradelist.append(pkgname)
    return npackages, nupgrades, nerrors, upgradelist, errorlist


def main():
    print('====================================================')
    print('UPGRADING ALL --USER PIP PACKAGES TO LATEST VERSION:')
    print('====================================================')
    pip_pkgs = get_pkgs() # created a generator
    npackages, nupgrades, nerrors, upgradelist, errorlist \
               = update_pkgs(pip_pkgs)
    print('\nNo. of --user pip packages = {}'.format(npackages))
    print('No. of upgrades            = {}'.format(nupgrades))
    print('No. of upgrade errors      = {}'.format(nerrors))
    if upgradelist:
        print('Package(s) upgraded:')
        pprint(upgradelist)
    if errorlist:
        print('Package(s) with upgrade error:')
        pprint(errorlist)
    print()


if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 10 ноября 2018

Финал upgrade_pip_packages.py .

Я нашел ответ на мой вопрос. По сути, мой сценарий должен был:

import sys

и внести следующие изменения:

cmd = [sys.executable, '-m', 'pip', 'list'] #Change here
completed = subprocess.run( cmd,
                            #shell=True, #switch this off
                            check=True,
                            stdout=subprocess.PIPE )

и

cmd = [sys.executable, '-m', 'pip', 'install', '--user', pkgname, '--upgrade'] #Change here
completed = subprocess.run( cmd,
                            #shell=True, #switch this off
                            check=True,
                            stdout=subprocess.PIPE )

Документация PyPA объяснение:

Рекомендуется писать {sys.executable} вместо простого Python в чтобы убедиться, что команды запускаются в установке Python соответствующий текущему ноутбуку (который может не совпадать Установка Python, на которую ссылается команда python).

$ pip --version
pip 18.1 from ~/.local/lib/python3.5/site-packages/pip (python 3.5)
$ pip3 --version
pip 18.1 from ~/.local/lib/python3.5/site-packages/pip (python 3.5)
...