Независимые функции платформы гденаходится


Я пытаюсь написать платформенно независимым языке Python (>=3.6.5) пакет, который имеет несколько Ява .Class файлы, которые нужно скомпилировать с помощью javac и работать java. Это достаточно простая задача, но мне нужно знать, если пользователь уже установлены и расположение исполняемого файла при условии, что ни один из них не находится на пути системы. Таким образом, я могу просто вызвать исполняемый файл, это путь через subprocess.run. Которые приводят меня к теме данного обзора независимым от платформы whereis команду.

import os, subprocess
from subprocess import CalledProcessError


def whereis(app):
    """Return a list of locations a given application.

    Relies on the `where` system command in Windows and the `whereis` command in Unix.

    Parameters
    ----------
    app : str
        Can be any application on the system path e.g. java.

    Returns
    -------
    result : list
        A list of locations where applications is installed.

    Useage
    ------
    >>>whereis('javac')
    'C:\\Program Files\\Java\\jdk1.8.0_162\\bin\\javac.exe'
    """

    result = None

    if os.name == "nt":# Windows
        try:
            result = subprocess.check_output("where {}".format(app))

        except CalledProcessError as err:
            print("Application ,",app,", not forund.",err)

    else:# Unix
        try:
            result = subprocess.check_output("whereis {}".format(app))

        except CalledProcessError as err:
            print("Application ,",app,", not found.",err)

    if result is None:
        print("")
        result = []
        return result

    else:
        result = result.decode().replace("\r", "").split("\n")
        result = list(filter(lambda x: len(x)>0, result))
        return result

Вопросы

  1. Есть ли стандартная функция библиотеки, которая уже покрывает это? Я не мог найти один, но это ничего не значит.
  2. Есть ли предостережения или пограничные случаи, которые я упустил?
  3. Может какие улучшения необходимо внести в код или строкой документации?


Комментарии
3 ответа

Пару мелочей:


  1. Если вы специально искали исполняемых файлов, вы можете использовать which вместо whereis команду. Из этого ответа, вы можете увидеть разницу между двумя используя whatis:


    $  whatis which
    which (1) - shows the full path of (shell) commands

    $ whatis whereis
    whereis (1) - locate the binary, source, and manual page files for a command



  2. Будьте последовательны. Вы использовали два разных стиля форматирования:

    "where {}".format(app)

    и

    "Application ,",app,", not forund.",err  # you also have a spelling mistake here (forund -> found) 

    Я рекомендую вам использовать первый


  3. Вы должны иметь по крайней мере два пробела перед рядный комментарий

  4. Вы должны поставить пробел после запятой в почти любой ситуации. (Эл.г: print("Application,",app,", not found.",err) -> print("Application,", app, ", not found.", err))

6
ответ дан 30 марта 2018 в 09:03 Источник Поделиться

Маленькая гнида:

# Split this into individual lines - much easier to read
import os, subprocess

Сократить дублирование кода и гнездования (а также использовать which) - это слишком сложно для чего это нужно (я не тестировал его, Хотя):

def whereis(app):
result = None

command = 'where'
if os.name != "nt":# Windows
command = 'which'

try:
result = subprocess.check_output("{} {}".format(command, app))
except CalledProcessError as err:
print("Application ,",app,", not found.",err)

if result is None:
return []

result = result.decode().splitlines()
return [line for line in result if len(line)]

4
ответ дан 30 марта 2018 в 10:03 Источник Поделиться

Вы можете использовать тернарный условный оператор для определения команды на уровне операционной системы, делая что немного логики, один лайнер. Если необходимые для предполагаемого использования, я не вижу смысла возвращать пустой список, просто вернуть None Если ваш скрипт не находит ничего. Если у вас есть немного кода, который выглядит примерно так:

if not paths:
# do something

Если paths - пустой список, он будет работать точно так же, если мы изменим его None.

import os
import subprocess

def whereis(app):
command = 'which' if os.name != 'nt' else 'where'
try:
result = subprocess.check_output('{} {}'.format(command, app), stderr=subprocess.STDOUT)
return result.decode().split()
except subprocess.CalledProcessError:
return

if __name__ == '__main__':
paths = whereis('notepad')

Выход:

['C:\\Windows\\System32\\notepad.exe', 'C:\\Windows\\notepad.exe']

2
ответ дан 31 марта 2018 в 11:03 Источник Поделиться