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

Я пытаюсь написать независимый от платформы пакет Python (> = 3.6.5), который содержит несколько java-файлов .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. Могут ли быть сделаны какие-либо общие улучшения для кода или docstring?
8 голосов | спросил James Draper 30 MarpmFri, 30 Mar 2018 22:19:05 +03002018-03-30T22:19:05+03:0010 2018, 22:19:05

3 ответа


6

Несколько мелочей:

  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) ) литий>
ответил яүυк 31 MaramSat, 31 Mar 2018 00:14:48 +03002018-03-31T00:14:48+03:0012 2018, 00:14:48
4

Малый nit:

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

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

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)]
ответил Srdjan Grubor 31 MaramSat, 31 Mar 2018 01:06:27 +03002018-03-31T01:06:27+03:0001 2018, 01:06:27
2

Вы можете использовать тернарный условный оператор для определения команды для каждой операционной системы, делая этот бит логики одним лайнером. Если это не необходимо для вашего предполагаемого использования, я не вижу смысла возвращать пустой список, просто верните 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']
ответил Lukasz Salitra 1 AMpSun, 01 Apr 2018 02:10:08 +030010Sunday 2018, 02:10:08

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132