Как условно оценить сценарий bash

Чтобы просмотреть установленные библиотеки в среде, я запускаю этот код в ячейке блокнота Jupyter Python:

%%bash
pip freeze

Это работает, но как условно выполнить этот код?

Это моя попытка:

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

def f(x1):
    if(x1 == True):
        f2()
    return x1

interact(f , x1 = False)


def f2():
    %%bash 
    pip freeze

Но оценка ячейки выдает ошибку:

  File "<ipython-input-186-e8a8ec97ab2d>", line 15
    pip freeze
             ^
SyntaxError: invalid syntax

Для создания флажка я использую ipywidgets: https://github.com/ipython/ipywidgets

Обновление: запуск pip freeze в check_call возвращает 0 результатов: введите здесь описание изображения

Бег

    %%bash 
    pip freeze

Возвращает установленные библиотеки, поэтому 0 неверно.

Правильно ли subprocess.check_call("pip freeze", shell=True)?

Обновление 2:

Это работает :

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import subprocess

def f(View):
    if(View == True):
        f2()

interact(f , View = False)


def f2():
    print(subprocess.check_output(['pip', 'freeze']))

person blue-sky    schedule 13.03.2017    source источник


Ответы (2)


Вы можете просто использовать стандартный способ Python:

import subprocess
print(subprocess.check_output(['pip', 'freeze']))

Тогда ваша функция будет работать в любой среде Python.

person John Zwinck    schedule 13.03.2017
comment
@blue-sky Код результата из check_call равен нулю, когда команда выполнена успешно, так что это полностью правильно (но, очевидно, не то, что вы ожидаете; но что тогда делать вы ожидаете?) - person tripleee; 13.03.2017
comment
Хотя вы хотите избежать ненужных и надоедливых shell=True; см. stackoverflow.com/questions/ 3172470/ - person tripleee; 13.03.2017
comment
@blue-sky: попробуйте обновленную версию — с явной печатью. - person John Zwinck; 13.03.2017

Короткое объяснение заключается в том, что в блокноте есть интерактивные команды, которые обрабатываются самим блокнотом еще до того, как интерпретатор Python их увидит. %%bash — пример такой команды; вы не можете поместить это в код Python, потому что это не Python.

Использование bash на самом деле ничего здесь не добавляет, само по себе использование оболочки предлагает много интерактивных преимуществ, и, конечно же, в интерактивной записной книжке предоставление пользователю доступа к оболочке является мощным механизмом, позволяющим пользователям выполнять внешние процессы; но в этом конкретном случае, при неинтерактивном выполнении, нет никаких реальных преимуществ от размещения оболочки между вами и pip, поэтому вы можете просто захотеть

 import subprocess
 if some_condition:
     p = subprocess.run(['pip', 'freeze'],
         stdout=subprocess.PIPE, universal_newlines=True)

(Обратите внимание на отсутствие shell=True, потому что нам здесь не нужна оболочка.)

Если вам нужен захваченный код выхода или вывод из pip freeze, они доступны как атрибуты возвращаемого объекта p. Подробнее см. в subprocess.run документации. Вкратце, p.returncode будет равно 0, если команда выполнена успешно, а вывод будет p.stdout.

В более старых версиях Python была разнообразная коллекция специальных оболочек вокруг subprocess.Popen, таких как check_call, check_output и т. д., но все они были включены в subprocess.run в последних версиях. Если вам нужно поддерживать версии Python до 3.5, устаревшие функции по-прежнему доступны, но, возможно, их следует избегать в новом коде.

person tripleee    schedule 13.03.2017