Теория и практика.

Исключительно для OS Linux. Для примера вы можете посмотреть код одной из утилит по этой Ссылке.

Утилита предназначена для небольшого переноса функционала Linux в Windows.

Потоковый ввод по конвееру через stdin в Windows как таковой не работает, но в Cygwin и MinGW вполне будет работать.


Для выполнения данного урока нам понадобится всего три модуля: sys, re и pathlib.

А начнем мы конструкций switch - case. На языках C/C++/Bash она упрощают нашу работу. Однако, её нет в языке Python. Но мы легко можем это исправить.

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

Выглядит это следующим образом:

def switch(case):
   return {
      "-stdin": 1,
      "-next": 2
   }.get(case, None)

Для использования можно воспользоваться следующим кодом:

b = input()
if switch(b) == 1: Выполняем некие действия
else: Иначе, выполняем что-то другое.

Else необязатальна, достаточно конструкции, где условие - истина.

Теперь стоит упомянуть ещё одну важную функцию, которая в скриптах Python упростить вашу жизнь.

Вместо того, чтобы вспоминать как проверить строку(массив, кортеж, список) на пустоту, можно просто записать себе функцию и забыть об этой проблеме. Однако помните, что если вы будет использовать эту функцию в классах, рекомендую указывать её как статический метод - @staticmethod.

def Enquiry(lis1):
   if len(lis1) == 0:
      return 0
   else:
      return 1

А вот теперь поговорим о потоках ввода и вводе значений по конвееру.

Поток ввода находится в модуле sys - sys.stdin. Там конечно есть методы sys.stdin.read() или sys.stdout.write("string"). Но они нам сегодня не понадобятся.

Важно помнить одно главное условие. Если поток ввода пустой - скорее всего при любых проверках у вас возникнет ошибка ввода данных. Вы конечно можете обработать её конструкцией try - except - finaly. Но гораздо проще и интереснее немного обойти её так, что никаких ошибок ни при каких условиях не возникало.

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

Немного запутанно, вот пример. Чтобы все вопросы отпали сами собой:

def main():
   st_din = False
   parameter = ""
   if len(sys.argv) >= 1:
      for count in range(len(sys.argv)):
         if switch(sys.argv[count]) == 1: st_din = True
         else: 
            if Enquiry(sys.argv[count]):
               parameter = sys.argv[count]
               st_din = False
   if st_din:
      for line in sys.stdin:
         if Enquiry(line):
            print(line)
   else:
      if Enquiry(parameter):
         print(parameter)
      else:
         print("Error!")

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

Для этого можно воспользоваться библиотекой re и неббольшим регулярным выражением.

Примерно так.

isdir = re.sub("^\s+|\n|\r|\s+$", '', line)

Где line - строка, из которой надо вырезать символы переноса строки, возврата каретки и другие. А isdir новая строка, без указанных символов.

И только после этого выполнять ваши действия с полученной строкой, например проверить её в качестве директории на существование:

if pathlib.Path(isdir).exists():

Ну а сегодня на этом всё. Продолжим в следующий раз.

Copyright © 08.02.2021 by Mikhail Artamonov