Лайфхаки

Маленькие, полезные хитрости

7 уровней построения интерфейсов командной строки на python. Выполняйте свои скрипты Python, как команды bash

11.08.2023 в 09:17

7 уровней построения интерфейсов командной строки на python. Выполняйте свои скрипты Python, как команды bash

Написание скриптов Python для создания интерфейсов командной строки (CLI) — широко используемый метод для DevOps и бэкенд разработки.

Ключом к реализации CLI в Python является встроенный модульargparse. Он предоставляет все необходимые функции и позволяет использовать скрипт Python в качестве командыbash.

В этой статье будут представлены некоторые важные моменты создания CLI с помощью Python на 7 уровнях сложности.

1. Запускаем базовый интерфейс командной строки с модулем argparse

Прежде всего, давайте создадим файл с именемtest.pyи сделаем простой парсер аргументов:

import argparse parser = argparse.ArgumentParser() parser.parse_args()

После того, как мы определили этот парсер, теперь мы можем получать аргументы из командной строки. Каждый экземплярArgumentParserсодержит параметр--help(или-hкачестве ярлыка) для вывода полезной информации.

$ python test.py --help

usage: test.py

optional arguments: -h, --help show this help message and exit

Однако из-за того, что мы не определили другие аргументы, следующий ввод вызовет ошибку:

$ python test.py 9

usage: test.py

test.py: error: unrecognized arguments: 9

2. Определяем позиционные аргументы

В командахbashесть два типа аргументов. Один позиционный, другой необязательный.

Например, командаcpимеет два позиционных аргумента:

$ cp source_file dest_file

source_fileуказывает источники копируемого файла. И аргументdest_fileуказывает место для копирования файла.

Мы также можем определить позиционный аргумент для нашего интерфейса командной строки Python:

import argparse parser = argparse.ArgumentParser() parser.add_argument("num", type=int) args = parser.parse_args() print(args.num**2)

Как видно из приведенного выше кода, мы определили имя аргумента какnumи указали его тип какint.

Теперь, если ввод из терминала является допустимым целым числом, наш скрипт Python будет печатать его квадрат:

$ python test.py 9

81

3. Добавляем больше полезной информации и описание

Как и многие команды Linux, хороший интерфейс командной строки должен предоставлять пользователям достаточно информации с помощью опции--help.

С этой целью мы можем указать специальную информацию для соответствующих функций модуляargparse.

import argparse parser = argparse.ArgumentParser(prog='get_square',description='A CLI to calculate the square of an integer.') parser.add_argument("num", type=int, help='An integer that needs to get the square value.') args = parser.parse_args() print(args.num**2)

Как показано выше, мы добавили информацию о программе и описании в экземплярArgumentParser, чтобы дать ему имя и подробное описание. Кроме того, мы дали функцииadd_argument()справочное сообщение, чтобы наши пользователи знали, для чего нужен этот аргумент.

Теперь давайте снова посмотрим на вывод опции-h:

$ python test.py -h

usage: get_square num

A CLI to calculate the square of an integer.

positional arguments:

num An integer that needs to get the square value.

optional arguments:

-h, --help show this help message and exit

Это удобнее и информативнее, не правда ли? :)

4. Определяем необязательные аргументы

Помимо позиционных аргументов, для многих интерфейсов командной строки также необходимы необязательные аргументы.

Click decorator python. Is it possible to reuse python @click.option decorators for multiple commands?

Solution 1:

You can build your own decorator that encapsulates the common options:

def common_options(function): function = click.option('--unique-flag-1', is_flag=True)(function) function = click.option('--bar', is_flag=True)(function) function = click.option('--foo', is_flag=True)(function) return function @click.command() @common_options def command(): pass

Solution 2:

Here is a decorator that uses the same principle from the previous answer:

def group_options(*options): def wrapper(function): for option in reversed(options): function = option(function) return function return wrapper opt_1 = click.option("--example1") opt_2 = click.option("--example2") opt_3 = click.option("--example3") @cli.command() @click.option("--example0") @group_options(opt_1, opt_2, opt_3) def command(example0, example1, example2, example3): pass

Solution 3:

If you want to add parameters to such a function, you need to wrap it once more:

def common_options(mydefault=True): def inner_func(function): function = click.option('--unique-flag-1', is_flag=True)(function) function = click.option('--bar', is_flag=True)(function) function = click.option('--foo', is_flag=True, default=mydefault)(function) return function return inner_func @click.command() @common_options(mydefault=False) def command(): pass

Python Decorators – How to Create and Use Decorators, To use a decorator ,you attach it to a function like you see in the code below. We use a decorator by placing the name of the decorator directly above the function we want to use it on. You prefix the decorator function with an @ symbol. @my_decorator_func def my_func (): pass. Here is a simple example.

Паттерн фабрика python. Factory Method in Python

Factory method is a creational design pattern which solves the problem of creating product objects without specifying their concrete classes.

The Factory Method defines a method, which should be used for creating objects instead of using a direct constructor call (newoperator). Subclasses can override this method to change the class of objects that will be created.

If you can’t figure out the difference between various factory patterns and concepts, then read our Factory Comparison .

Complexity:

Popularity:

Usage examples: The Factory Method pattern is widely used in Python code. It’s very useful when you need to provide a high level of flexibility for your code.

Identification: Factory methods can be recognized by creation methods that construct objects from concrete classes. While concrete classes are used during the object creation, the return type of the factory methods is usually declared as either an abstract class or an interface.

Conceptual Example

This example illustrates the structure of the Factory Method design pattern. It focuses on answering these questions:

Factory Method in Python: A Creational Design Pattern

Factory method is a creational design pattern which solves the problem of creating product objects without specifying their concrete classes.

Complexity and Popularity

Complexity: Easy

Popularity: High

Usage Examples

The Factory Method pattern is widely used in Python code. It’s very useful when you need to provide a high level of flexibility for your code.

Identification

Factory methods can be recognized by creation methods that construct objects from concrete classes. While concrete classes are used during the object creation, the return type of the factory methods is usually declared as either an abstract class or an interface.

Example

This example illustrates the structure of the Factory Method design pattern. It focuses on answering these questions:

  • How to define an interface for creating an object, but let subclasses decide which class to instantiate.
  • How to provide a way to encapsulate a complex creation process.
  • How to provide a way to support different product representations.

class Creator: def __init__(self): self.product = None def factory_method(self): return ConcreteProductA() def some_operation(self): product = self.factory_method() result = product.do_something() return result class ConcreteCreatorA(Creator): def factory_method(self): return ConcreteProductA() class ConcreteCreatorB(Creator): def factory_method(self): return ConcreteProductB() class Product: def do_something(self): pass class ConcreteProductA(Product): def do_something(self): return "ConcreteProductA: The result of this method is some encapsulated action." class ConcreteProductB(Product): def do_something(self): return "ConcreteProductB: The result of this method is some other action." # Client code creator = ConcreteCreatorA() print(creator.some_operation()) # Output: ConcreteProductA: The result of this method is some encapsulated action. creator = ConcreteCreatorB() print(creator.some_operation()) # Output: ConcreteProductB: The result of this method is some other action.

This example shows how the Factory Method pattern can be used in Python to create objects without specifying their concrete classes.

  • What classes does it consist of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Python cli. Getting Started With CLIs in Python: sys.argv vs argparse

Python comes with a couple of tools that you can use to write command-line interfaces for your programs and apps. If you need to quickly create a minimal CLI for a small program, then you can use theattribute from themodule. This attribute automatically stores the arguments that you pass to a given program at the command line.

Usingsys.argvto Build a Minimal CLI

As an example of usingargvto create a minimal CLI, say that you need to write a small program that lists all the files in a given directory, similar to whatlsdoes. In this situation, you can write something like this:

sys.argv. The first item insys.argvis always the program’s name. The second item will be the target directory. The app shouldn’t accept more than one target directory, so theargs_countmust not exceed2.

After checking the content ofsys.argv, you create a pathlib.Path object to store the path to your target directory. If this directory doesn’t exist, then you inform the user and exit the app. The forloop lists the directory content, one entry per line.

If you run the script from your command line, then you’ll get the following results:

$ python ls_argv.py sample/ hello.txt lorem.md realpython.md $ python ls_argv.py You must specify the target directory $ python ls_argv.py sample/ other_dir/ One argument expected, got 2 $ python ls_argv.py non_existing/ The target directory doesn't exist

Your program takes a directory as an argument and lists its content. If you run the command without arguments, then you get an error message. If you run the command with more than one target directory, you also get an error. Running the command with a nonexistent directory produces another error message.

Even though your program works okay, parsing command-line arguments manually using thesys.argvattribute isn’t a scalable solution for more complex CLI apps. If your app needs to take many more arguments and options, then parsingsys.argvwill be a complex and error-prone task. You need something better, and you get it in Python’sargparsemodule.

Горячие клавиши терминала Linux

Терминал Linux - это одно из преимуществ этого семейства операционных систем. С помощью терминала можно быстро выполнить многие действия в операционной системе. Команды можно выполнять не только по одиночке, но и группировать между собой с помощью различных операторов перенаправления ввода и управления выполнением.

Однако с терминалом можно работать ещё более эффективно зная горячие клавиши. В этой небольшой статье мы рассмотрим основные горячие клавиши терминала Linux, которые вы можете использовать в своей работе.

Горячие клавиши терминала Linux

Общие:

  • Ctrl+Alt+T - в дистрибутивах, основанных на Ubuntu это сочетание клавиш используется для открытия терминала.
  • Tab - эта клавиша используется для автодополнения в терминале. Вам достаточно набрать начало какой-нибудь команды, затем нажать её и команда предложит доступные варианты или завершит её если она одна.
  • Ctrl+L - очистить весь вывод терминала.
  • Ctrl+S - приостановить вывод терминала.
  • Ctrl+Q - возобновить вывод если он был приостановлен.
  • Ctrl+C - отправить команде сигнал SigInt для её завершения.
  • Ctrl+Z - свернуть текущую команду в фоновый режим.

История команд:

  • Стрелки вверх и вниз - используются для перемещения вперед и назад по истории команд.
  • Ctrl+r - можно использовать для поиска по истории команд.
  • Ctrl+p - предыдущая команда в истории команд.
  • Ctrl+n  - следующая команда в истории команд.
  • Ctrl+g  - если вы находитесь в режиме поиска, завершает поиск.
  • Ctrl+o  - выполнить найденную поиском команду.
  • Alt+. - использовать последнее слово предыдущей команды.

Перемещение курсора:

  • Ctrl+a - перейти в начало строки.
  • Ctrl+e - перейти в конец строки.
  • Alt+b - перейти влево на одно слово.
  • Alt+f - перейти в право на одно слово.
  • Ctrl+b - перейти влево на один символ.
  • Ctrl+f - перейти вправо на один символ.
  • Ctrl+xx - перейти в конец или в начало строки.

Редактирование:

  • Ctrl+u - вырезать строку до позиции курсора.
  • Alt+Del - удалить слово перед курсором.
  • Alt+d - удалить слово после курсора.
  • Ctrl+d - удалить символ под курсором.
  • Ctrl+h - удалить символ под курсором.
  • Ctrl+w - вырезать слово под курсором.
  • Ctrl+k - вырезать строку от позиции курсора до конца строки
  • Alt+t - поменять текущее слово с предыдущим.
  • Ctrl+t - поменять местами два символа перед курсором.
  • Esc+t - поменять местами два слова перед курсором.
  • Ctrl+y - вставить то, что было вырезано.
  • Alt+u - сделать верхний регистр символов от позиции курсора до конца текущего слова.
  • Alt+l - сделать нижний регистр символов от позиции курсора до конца слова.
  • Alt+r - вернуть строку в исходное состояние.
  • Ctrl+_ - отменить последнее действие со строкой.

Все перечисленные выше команды будут прекрасно работать в командной оболочке bash. Но если вы используете другие оболочки, то некоторые горячие клавиши терминала могут не работать или вести себя по другому. А пока дайте рассмотрим примеры использования некоторых из них.

Очень полезна возможность поиска по истории команд. Например, вы хотите найти команду openvpn, которую выполняли ранее. Просто нажмите Ctrl+R и начните набирать команду. Оболочка подскажет вам как команда завершалась:

Для выполнения команды достаточно нажать Enter или Ctrl+o. Конечно, можно было бы листать все команды по очереди с помощью клавиши стрелка вверх или сочетания Ctrl+p , но так гораздо удобнее.

Довольно полезно при работе с историей команд сочетание клавиш Alt+r . Вы можете найти в истории команд какую-нибудь команду, а затем немного изменить её. С помощью этого сочетания клавиш вы можете вернуть команду к исходному состоянию.

Иногда команда выводит информацию слишком быстро. Тогда вы можете приостановить вывод с помощью сочетания клавиш Ctrl+S . Можно поэкспериментировать с этим сочетанием и командой ping :

Для возобновления вывода надо нажимать уже не Ctrl+S , а Ctrl+Q .

Выводы

В этой статье мы рассмотрели некоторые полезные горячие клавиши терминала Linux. С помощью них вы сможете работать с терминалом быстрее. А какие горячие клавиши знаете вы? Напишите в комментариях!

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.