Теория и практика.
Исключительно для 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():
Ну а сегодня на этом всё. Продолжим в следующий раз.