Проверяем rewrite’ы
Не считайте себя гуру в написании регулярных выражений, в любом случае вы ошибетесь и не заметите этого. В сложном регулярном выражении нельзя быть уверенным на сто процентов. Поэтому самое простое, это исключить такие выражения из использования, в пользу более чистого и понятного кода. Вот пример:
ПЛОХО:
rewrite ^/(.*)$ http://domain.com/$1 permanent;
ХОРОШО:
rewrite ^http://domain.com$request_uri? permanent;
ЕЩЕ ЛУЧШЕ:
return 301 http://domain.com$request_uri;
Посмотрети, на первый вариант, потом на последний, потом опять на первый и опять на последний. Ну что? Первый реврайт запоминает полный путь без учета начального слеша и затем помещает этот путь вместо плейсхолдера . Однако используя встроенную переменную мы спокойно можем избавится от всей этой магии с регулярными выражениями.
Абсолютный путь в URL
Абсолютный путь в URL означает путь от корня сайта. Корень сайта — это папка, которая содержит публичную часть сайта, т.е. доступную извне.
По-умолчанию корень сайта — это сама папка с сайтом, например site.ru, но зачастую её меняют на site.ru/public, чтобы часть скриптов нельзя было запустить по прямой ссылке в браузере.
- http://test.ru/article.php — полный путь с протоколом и доменом
- //test.ru/article.php — полный путь без протокола (берётся из текущей страницы). Содержит два слеша в начале.
- /article.php — полный путь без протокола и домена (берутся из текущей страницы). Содержит слеш в начале.
Второй и третий варианты удобны тем, что при миграции с http на https и обратно все ссылки автоматически сменят протокол, не нужно будет бегать по всему сайту и менять вручную.
Лично я практически всегда использую третий вариант, кроме случаев, когда нужно указать ссылку на другой поддомен (blog.site.ru, shop.site.ru и т.д.).
Абсолютные и относительные пути в ArcMap
При создании документа ArcMap (либо ArcScene, либо ArcGlobe) вы можете указать, что сохраняться будут относительные пути. Для установки этой опции выберите Файл (File)>Свойства документа карты (Map Document Properties). Здесь вы можете указать, будете ли вы хранить абсолютные или относительные пути.
При сохранении документа с относительными путями приложение преобразует пути в относительные (используя точку и двойную точку) в зависимости от того, где вы сохранили документ (т.е. от текущей директории). Например, если ваш документ сохранен в
и данными одного из слоев являются
то в Newmap.mxd записано следующее:
Когда вы снова открываете Newmap.mxd, ArcMap преобразует сохраненные относительные пути (с обозначением с помощью точки и двух точек) обратно в абсолютные, которые отображаются как источник данных слоя. Эта конвертация всегда зависит от местоположения документа карты (текущей директории).
Когда использовать условие else
Используйте условие else после блока try-except. Оно будет выполняться в том случае, если исключение не будет выдано. Оператор else всегда должен предшествовать блокам except .
В блоках else можно добавить код, который необходимо запустить, если ошибок не возникло.
В приведенном ниже примере видно, что цикл while работает бесконечно. Код запрашивает значение у пользователя, а затем анализирует его с помощью встроенной функции . Если пользователь вводит нулевое значение, блок except будет заблокирован. В противном случае код будет проходить через блок else.
while True: # Введете с консоли целое число. x = int(input()) # Разделите 1 на x, чтобы протестировать ошибку try: result = 1 / x except: print("Error case") exit(0) else: print("Pass case") exit(1)
2.1. Запись в пустой файл в Python
Самый простой способ сохранения данных, это записать их в файл. Чтобы записать текс в файл, требуется вызвать open() со вторым аргументом, который сообщит Python что требуется записать файл. Пример программы записи простого сообщения в файл на Python:
filename = ‘memory.txt’
with open(filename, ‘w’) as file:
file.write(«Язык программирования Python»)
Для начала определим название и тип будущего файла и сохраним в переменную filename. Затем при вызове функции open() передадим два аргумента. Первый аргумент содержит имя открываемого файла. Второй аргумент ‘ w ‘ сообщает Python, что файл должен быть открыт в режиме записи. Во второй строчке метод write() используется для записи строки в файл. Открыв файл ‘ memory.txt ‘ вы увидите в нем строку:
Язык программирования Python
Получившийся файл ничем не отличается от любых других текстовых файлах на компьютере, с ним можно делать все что угодно.
Важно: Открывая файл в режиме записи ‘ w ‘, если файл уже существует, то Python уничтожит его данные перед возвращением объекта файла. Файлы можно открывать в режимах:
Файлы можно открывать в режимах:
- чтение ‘ r ‘
- запись ‘ w ‘
- присоединение ‘ a ‘
- режим как чтения, так и записи ‘ r+ ‘
Иерархия исключений
В Python есть иерархия исключений. Это происходит из-за того, что их классы наследуются друг от друга. Вот полный список:
BaseException — базовое исключение, от которого берут начало все остальные
+SystemExit — исключение, порождаемое функцией sys.exit при выходе из программы
+KeyboardInterrupt — порождается при прерывании программы пользователем (обычно сочетанием клавиш Ctrl+C)
+GeneratorExit — порождается при вызове метода close объекта generator
+Exception – исключения
++StopIteration — порождается встроенной функцией next, если в итераторе больше нет элементов
++StopAsyncIteration — используется для остановки асинхронного прохода
++ArithmeticError — арифметическая ошибка
+++FloatingPointError
+++OverflowError
+++ZeroDivisionError
++AssertionError— выражение в функции assert ложно
++AttributeError — объект не имеет данного атрибута (значения или метода)
++BufferError— операция, связанная с буфером, не может быть выполнена
++EOFError— функция наткнулась на конец файла и не смогла прочитать то, что хотела
++ImportError — не удалось импортирование модуля или его атрибута
+++ModuleNotFoundError
++LookupError— некорректный индекс или ключ
+++IndexError
+++KeyError
++MemoryError— недостаточно памяти
++NameError — не найдено переменной с таким именем
+++UnboundLocalError
++OSError — ошибка, связанная с системой
+++BlockingIOError
+++ChildProcessError
+++ConnectionError
++++BrokenPipeError
++++ConnectionAbortedError
++++ConnectionRefusedError
++++ConnectionResetError
+++FileExistsError
+++FileNotFoundError
+++InterruptedError
+++IsADirectoryError
+++NotADirectoryError
+++PermissionError
+++ProcessLookupError
+++TimeoutError
++ReferenceError — попытка доступа к атрибуту со слабой ссылкой
++RuntimeError — возникает, когда исключение не попадает ни под одну из других категорий
+++NotImplementedError
+++RecursionError
++SyntaxError — синтаксическая ошибка
++IndentationError
++TabError
++SystemError — внутренняя ошибка
++TypeError — операция применена к объекту несоответствующего типа
++ValueError — функция получает аргумент правильного типа, но некорректного значения
+++UnicodeError
++++UnicodeDecodeError
++++UnicodeEncodeError
++++UnicodeTranslateError
++Warning — предупреждение
+++DeprecationWarning
+++PendingDeprecationWarning
+++RuntimeWarning
+++SyntaxWarning
+++UserWarning
+++FutureWarning
+++ImportWarning
+++UnicodeWarning
+++BytesWarning
+++ResourceWarning
Обработка FileNotFoundError
При работе с файлами в Python часто возникает ошибка .
В следующем примере мы попытаемся открыть файл my_file.txt, указав его путь в функции . Мы хотим прочитать файл и вывести его содержимое.
Однако мы еще не создали этот файл в указанном месте.
my_file = open("/content/sample_data/my_file.txt") contents = my_file.read() print(contents)
Поэтому, попытавшись запустить приведенный выше фрагмент кода, мы получим :
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-4-4873cac1b11a> in <module>() ----> 1 my_file = open("my_file.txt") FileNotFoundError: No such file or directory: 'my_file.txt'
А с помощью и мы можем сделать следующее:
- Попробуем открыть файл в блоке .
- Обработаем в блоке , сообщив пользователю, что он попытался открыть несуществующий файл.
- Если блок завершается успешно и файл действительно существует, прочтем и распечатаем содержимое.
- В блоке закроем файл, чтобы не терять ресурсы. Файл будет закрыт независимо от того, что происходило на этапах открытия и чтения.
try: my_file = open("/content/sample_data/my_file.txt") except FileNotFoundError: print(f"Sorry, the file does not exist") else: contents = my_file.read() print(contents) finally: my_file.close()
Обратите внимание: мы обработали ошибку как исключение, и программа завершает работу, отображая следующее сообщение:
Sorry, the file does not exist
Теперь рассмотрим случай, когда срабатывает блок . Файл my_file.txt теперь присутствует по указанному ранее пути.
Вот содержимое этого файла:
Теперь повторный запуск нашего кода работает должным образом.
На этот раз файл my_file.txt присутствует, поэтому запускается блок и содержимое распечатывается, как показано ниже:
Надеемся, теперь вы поняли, как обрабатывать исключения при работе с файлами.
Путь относительно корня сайта
Вы наверное уже поняли что пути относительно документа используются очень часто. Но при их использовании существует одна проблема. Которая заключается в том, что при смене структуры директорий, пути придется менять.
Но такая проблема решаема при использовании путей относительно корня сайта. Где путь указывается от корневой директории до документа.
Все пути относительно корня сайта начинаются со знака . Только здесь, в отличии от путей относительно документа этот знак используется для указания корневой директории. Потому, что он используется в начале пути.
Путь относительно корня сайта позволяет перемещать некоторые файлы, без ущерба для ссылок. Этот тип пути Вы сможете использовать только на web-сервере в интернете, или на web-сервере расположенном на локальной машине.
Корневой относительный путь не содержит ни протокола http, ни доменного имени. И как я уже говорил начинается с указания символа , который указывает на корневую директорию. В этой директории обычно располагается индексный файл главной страницы.
Например, /images/products.png обозначает, что файл products.png находится в папке images, которая расположена в корневом каталоге.
Самый простой способ определить корневой относительный путь — взять абсолютный и отбросить http:// и имя хоста.
Следующий код предназначен для вставки изображения «contact.png».
<img src="images/contact.png"> |
Я надеюсь, что Вы уже знаете какой тип пути использовался в вышеприведённом коде. Если нет, тогда посмотрите приведённое выше определение пути относительно документа.
Теперь, когда посетитель зайдет на такие страницы сайта как home.html, contact.ntml, он увидит прекрасно отображаемую страницу. В каждую из которых вставлен файл _contact.html, в который, в свою очередь, вставлено изображение contact.png.
Другими словами зайдя, к примеру, на страницу home.html, происходит следующее: «Выполняется код основной страницы home.html. Затем вставляется и исполняется код страницы _contact.html. Код страницы _contact.html, говорит что нужно перейти в директорию images и взять от туда изображение contact.png«.
Если опустить сам код для вставки, то все работает отлично. Но вот если запустить страницу products.html, то произойдет ошибка. Так как код будет пытаться найти директорию images и файл contact.png в директории products. Но такой директории там не существует, из за чего собственно и возникает проблема.
Становится ясным, что использовать путь относительно документа здесь нельзя.
Конечно здесь можно использовать абсолютный путь. О плюсах и минусах данного подхода я говорил выше.
В общем говоря, это одна из ситуаций, когда нужно использовать путь относительно корня сайта. При использовании пути относительно корня сайта, ссылка будет всегда начинаться с корневого каталога(корня сайта). Такой тип пути позволит использовать код для вставки, например изображения, независимо от иерархии сайта, и его директорий.
Использование пути относительно корня сайта в вышеприведённом примере, позволит избежать проблем, со вставкой изображения. Потому как независимо от того где будет использовать такой тип пути, он всегда найдет указанный в нем файл.
Путь относительно корня сайта, очень похож на путь относительно документа. Для того что бы создать путь относительно корня сайта, нужно добавить символ в начало пути.
<img src="/images/contact.png"> |
Теперь изображение будет корректно вставляться на любой из страниц сайта.
Надеюсь я немного помог Вам разобраться в том какие пути существуют, и в том когда и где они используются. Теперь можно использовать все типы пути по прямому их назначению.
Перенаправление запросов для отсутствующих доменов (перенаправление по умолчанию)
Если обращение к веб-серверу идет по IP-адресу или домену, который не прописан в конфигурационном файле, можно перенаправить весь трафик на домен по умолчанию:
server {
listen 80 default_server;
return 302 https://welcome.domain.ru$request_uri;
}
или независимо от протокола:
server {
listen 80 default_server;
return 302 $scheme://welcome.domain.ru$request_uri;
}
server {
listen 443 ssl default_server;
return 302 $scheme://welcome.domain.ru$request_uri;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
}
* $scheme позволяет перевести запрос на тот же протокол (http или https), по которому он был инициирован.
* если nginx должен слушать и обрабатывать запросы по https, необходимо указывать в настройках пути к сертификатам.
HTML веб-ссылка: Абсолютные пути
Описать абсолютный путь означает полностью указать адрес определенного документа, перечислив все каталоги и подкаталоги, через которые мы должны пройти, чтобы достичь его. Чтобы лучше понять, давайте рассмотрим этот адрес:
<a href="https://gospodaretsva.com/css/index.html">сайт</a>
Ссылка указывает абсолютный путь и ссылается на конкретный каталог. В этом случае:
Http: // | Указывает браузеру использовать протокол просмотра веб-страниц (http) |
gospodaretsva.com | Указывает на ссылку на сайт gospodaretsva.com |
CSS / | Указывает, что указанный ресурс находится в папке «css» |
index.html | Указывает, что файл, который будет связан, называется «index.html» |
Для упрощения можно также сказать, что абсолютная ссылка — это URL, который мы обычно находим в адресной строке.
Абсолютные пути используются в основном при написании ссылок на ресурсы, расположенные на сторонних сайтах (которые не принадлежат проекту).
Встроенные редиректы WordPress
Очевидно, что выше описана простая ситуация
На нее достаточно обратить внимание и исправить. Но не всегда бывает так просто
Например, вы сами не настраивали редирект урлов без слеша на урлы со слешом, он вам не нужен. Но, к примеру, WordPress реализует подобный редирект своими средствами. В итоге, при запросе http://site.ru/catalog вы получите такую картину с редиректами.
# curl -I -L http://site.ru/catalog HTTP/1.1 301 Moved Permanently Server: nginx Content-Type: text/html Content-Length: 162 Connection: keep-alive Location: https://site.ru/catalog HTTP/2 301 server: nginx content-type: text/html; charset=utf-8 location: https://site.ru/catalog/ x-powered-by: PHP/7.4.2 x-redirect-by: WordPress HTTP/2 200 server: nginx content-type: text/html; charset=utf-8 vary: Accept-Encoding
Сначала nginx сделал редирект на https, так как вы это настроили у него в конфигурации, а потом wordpress на страницу со слешом на конце. В итоге у вас два редиректа, а надо один. Причем, два редиректа получились не по вашей воле
Если не обратите на это внимание, так и будете с ними жить. По факту, все типовые редиректы лучше сразу реализовывать в одном месте в веб сервере
Синтаксис конструкции try и except
Для начала разберем синтаксис операторов try и except в Python. Общий шаблон представлен ниже:
try: # В этом блоке могут быть ошибки except <error type>: # Сделай это для обработки исключения; # выполняется, если блок try выбрасывает ошибку else: # Сделай это, если блок try выполняется успешно, без ошибок finally: # Этот блок выполняется всегда
Давайте посмотрим, для чего используются разные блоки.
Блок try
Блок — это блок кода, который вы хотите попробовать выполнить. Однако во время выполнения из-за какого-нибудь исключения могут возникнуть ошибки. Поэтому этот блок может не работать должным образом.
Блок except
Блок запускается, когда блок не срабатывает из-за исключения. Инструкции в этом блоке часто дают некоторый контекст того, что пошло не так внутри блока .
Если собираетесь перехватить ошибку как исключение, в блоке нужно обязательно указать тип этой ошибки. В приведенном выше сниппете место для указания типа ошибки обозначено плейсхолдером .
можно использовать и без указания типа ошибки. Но лучше так не делать. При таком подходе не учитывается, что возникающие ошибки могут быть разных типов. То есть вы будете знать, что что-то пошло не так, но что именно произошло, какая была ошибка — вам будет не известно.
При попытке выполнить код внутри блока также существует вероятность возникновения нескольких ошибок.
Например, вы можете попытаться обратиться к элементу списка по индексу, выходящему за пределы допустимого диапазона, использовать неправильный ключ словаря и попробовать открыть несуществующий файл – и все это внутри одного блока .
В результате вы можете столкнуться с , и . В таком случае нужно добавить столько блоков , сколько ошибок ожидается – по одному для каждого типа ошибки.
Блок else
Блок запускается только в том случае, если блок выполняется без ошибок. Это может быть полезно, когда нужно выполнить ещё какие-то действия после успешного выполнения блока . Например, после успешного открытия файла вы можете прочитать его содержимое.
Блок finally
Блок выполняется всегда, независимо от того, что происходит в других блоках. Это полезно, когда вы хотите освободить ресурсы после выполнения определенного блока кода.
Примечание: блоки и не являются обязательными. В большинстве случаев вы можете использовать только блок , чтобы что-то сделать, и перехватывать ошибки как исключения внутри блока .
Марк Лутц «Изучаем Python»
Скачивайте книгу у нас в телеграм
Скачать
×
Итак, теперь давайте используем полученные знания для обработки исключений в Python. Приступим!
Как создать свой тип Exception
В Python можно создавать свои исключения. При этом есть одно обязательное условие: они должны быть потомками класса
С помощью контролируются и обрабатываются ошибки в приложении. Это особенно актуально для критически важных частей программы, где любые «падения» недопустимы (или могут привести к негативным последствиям). Например, если программа работает как «демон», падение приведет к полной остановке её работы. Или, например, при временном сбое соединения с базой данных, программа также прервёт своё выполнения (хотя можно было отловить ошибку и попробовать соединиться в БД заново).
Вместе с можно использовать дополнительные блоки. Если использовать все блоки описанные в статье, то код будет выглядеть так:
Подробнее о работе с исключениями в Python можно ознакомиться в официальной документации.
Перехват исключений
Если Вам не подходит стандартное поведение языка при возникновении исключений – остановка выполнения, Вы можете перехватить исключение и обработать его. Для таких ситуаций и существует конструкция try except. Данный механизм Python позволяет контролировать непредвиденные ситуации и действовать исходя из новых условий. Проиллюстрируем это используя предыдущий пример:
Копировать
Несколько блоков except
Можно использовать несколько блоков except и обрабатывать в каждом блоке отдельный вид ошибки. Немного перепишем программу из предыдущего примера:
Копировать
Хорошей практикой является написание сперва блоков для конкретных ошибок, а затем для общих случаев, поскольку всех ситуаций не предусмотреть:
Копировать
Вложенные блоки и else
Блоки try-except можно вкладывать друг в друга, если в этом есть необходимость.
Здесь же мы используем блок else. Этот блок должен содержать код, который выполнится если не возникнет исключений.
Копировать
Кстати, здесь допущена логическая ошибка. Найдёте?
Finally
Встречаются ситуации, когда необходимо выполнить какую-то часть кода в независимости от того, было исключение или нет. Для этого существует блок finally:
Копировать
Абсолютный путь
Когда ссылка представляет из себя полный URL файла или страницы, это и есть абсолютный путь. При этом в адресе должен присутствовать используемый протокол. Например, http://www.uamedwed.com — это абсолютный путь к конкретному веб-сайту. В данном случае абсолютный путь к главной странице моего блога. Где протоколом является http, а www.uamedwed.com доменом(именем).
В основном абсолютный путь используется, тогда, когда нужно сослаться на другой сайт. Иными словами если Вы хотите отправить посетителя на другой сайт, то нужно использовать абсолютный путь. Хотя, такой путь можно использовать и на собственном сайте. Но многие придерживаются того, что ссылки внутри сайта должны быть относительными.
Использование абсолютного пути может повлечь за собой некоторые проблемы. Например при переносе сайта с локальной машины на сервер(это в том случае, если вы использовали на локальной машине адреса в виде http://localhost/sitename.ua/…). Трудности могут возникнуть, тогда, когда появится необходимость в смене домена(имени сайта). Хотя, все эти трудности решаемы, но на них придётся потратить некоторое количество времени.
Когда есть минусы, значит должны быть и плюсы. Возьмём к примеру такую ситуацию, как кража контента с вашего сайта. На практике я уже не раз убедился в том, что текст воруют целиком, при этом не оставляя обратной ссылки на оригинал. Так вот, при использовании абсолютных путей, можно получить обратные ссылки с сайта, на котором находится сворованный контент. Но это только в том случае если у Вас внутренняя перелинковка осуществлялась с использованием абсолютных путей. Хотя это не всегда работает, но я уже не раз замечал появление ссылок с чужих сайтов, на которых был расположен мой контент.
Немного отступив от темы хочу вкратце рассказать про то что такое URL.