Как я могу написать программу на Python для создания итеративных кластеров для алгоритма k-средних?

Вызов внешней команды в Python

Простой, используйте subprocess.run, который возвращает объект CompletedProcess:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

Почему?

Начиная с Python 3.5, в документации рекомендуется subprocess.run :

. Рекомендуемым подходом к вызову подпроцессов является использование функции run () для всех случаев использования, которые он может обрабатывать.

Ниже приведен пример простейшего возможного использования - и он выполняет точно так же, как и задано:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

run ждет завершения команды, а затем возвращает объект CompletedProcess. Он может вместо этого поднимать TimeoutExpired (если вы дадите ему аргумент timeout=) или CalledProcessError (если он терпит неудачу и вы пройдете check=True).

Как вы могли бы сделать вывод из приведенного выше примера, stdout и stderr оба по умолчанию передаются по вашему собственному stdout и stderr.

Мы можем проверить возвращаемый объект и увидеть команду, которая была указана, и код возврата:

>>> completed_process.args
'python --version'
>>> completed_process.returncode
0

Захват output

Если вы хотите захватить вывод, вы можете передать subprocess.PIPE в соответствующие stderr или stdout:

>>> cp = subprocess.run('python --version', 
                        stderr=subprocess.PIPE, 
                        stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''

(я нахожу это интересным и слегка что информация о версии попадает в stderr вместо stdout.)

Передача списка команд

Можно легко перейти от ручного предоставления командной строки (например, вопрос) к предоставлению строка построена программно. Не стройте строки программно. Это потенциальная проблема безопасности. Лучше предположить, что вы не доверяете входным данным.

>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n  This is indented.\r\n'

Обратите внимание, что только args следует передавать по позициям.

Полная подпись

Вот фактическая сигнатура в источнике и как показано на рисунке help(run):

def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

popenargs и kwargs присваиваются конструктору Popen. input может быть строкой байтов (или unicode, если указать кодировку или universal_newlines=True), которые будут переданы по каналу в stdin подпроцесса.

Документация описывает timeout= и check=True лучше, чем I can:

Аргумент timeout передается Popen.communicate (). Если истечет время ожидания, дочерний процесс будет убит и будет ждать. Исключение TimeoutExpired будет повторно поднято после завершения дочернего процесса.

Если проверка верна, и процесс завершается с ненулевым кодом выхода, будет вызвано исключение CalledProcessError. Атрибуты этого исключения содержат аргументы, код выхода и stdout и stderr, если они были захвачены.

, и этот пример для check=True лучше, чем один, который я мог бы придумать:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

Расширенная подпись

Вот расширенная подпись, указанная в документации:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

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

Popen

При использовании Popen вместо этого? Я бы изо всех сил пытался найти прецедент, основанный только на аргументах. Однако прямое использование Popen даст вам доступ к его методам, включая poll, «send_signal», «terminate» и «wait».

Вот подпись Popen, как указано в источнике . Я думаю, что это наиболее точное инкапсулирование информации (в отличие от help(Popen)):

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None):

Но более информативным является документация Popen :

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
                 stdout=None, stderr=None, preexec_fn=None, close_fds=True,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

Выполнить дочернюю программу в новом процессе. В POSIX класс использует os.execvp () - подобное поведение для выполнения дочерней программы. В Windows класс использует функцию Windows CreateProcess (). Аргументы для Popen следующие.

Понимание оставшейся документации в Popen будет оставлено как упражнение для читателя.

0
задан Pikachu the Watermelon Wizard 10 March 2019 в 01:50
поделиться