Передача набора значений. Продолжение.
Также можно задавать альтернативные значения для всего шаблона в том числе с помощью объектов других классов:
Здесь первый шаблон соответствует любому объекту Person, у которого атрибут name = "Tom, и любому объекту Student, у которого атрибут name = "Tomas".
Второй шаблон - case Person(name=name) | Student(name=name) соответствует любому объекту Person и Student.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #классы
Также можно задавать альтернативные значения для всего шаблона в том числе с помощью объектов других классов:
Здесь первый шаблон соответствует любому объекту Person, у которого атрибут name = "Tom, и любому объекту Student, у которого атрибут name = "Tomas".
Второй шаблон - case Person(name=name) | Student(name=name) соответствует любому объекту Person и Student.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #классы
Позиционные параметры
В примерах из прошлых постов для определения атрибутов прописывалось их имя: case Person(name="Tom", age=37). Но если используется куча шаблонов, и в каждом необходимо связать атрибуты объекта с некоторыми значениями или переменными, то постоянное упоминание атрибутов можно несколько раздуть код. Но Python также позволяет использовать позиционные параметры, смотрим код:
Обратите внимание в классе Person на вызов функции. Благодаря этому Python будет знать, что при указании атрибутов атрибут name будет идти первым, а атрибут age - вторым.
И таким образом, в шаблонов не нужно указывать имя атрибута: case Person("Tom", 37) - Python сам сопоставит атрибуты и значения/переменные на основе их позиции.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #классы
В примерах из прошлых постов для определения атрибутов прописывалось их имя: case Person(name="Tom", age=37). Но если используется куча шаблонов, и в каждом необходимо связать атрибуты объекта с некоторыми значениями или переменными, то постоянное упоминание атрибутов можно несколько раздуть код. Но Python также позволяет использовать позиционные параметры, смотрим код:
Обратите внимание в классе Person на вызов функции. Благодаря этому Python будет знать, что при указании атрибутов атрибут name будет идти первым, а атрибут age - вторым.
И таким образом, в шаблонов не нужно указывать имя атрибута: case Person("Tom", 37) - Python сам сопоставит атрибуты и значения/переменные на основе их позиции.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #классы
guards или ограничения шаблонов
Guard или ограничения шаблонов позволяют установить дополнительные условия, которым должно соответсвовать выражение. Ограничение задается сразу после шаблона с помощью ключевого слова if, после которого идет условие ограничения:
Здесь первый шаблон соответствует любому объекту Person, у которого атрибут age меньше 18. Собственно часть if age < 18 и представляет ограничение. Соответственно, если у пользователя возраст меньше 18, то будет выводьтся одно сообщение, если больше 18, то другое.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #guards #шаблоны
Guard или ограничения шаблонов позволяют установить дополнительные условия, которым должно соответсвовать выражение. Ограничение задается сразу после шаблона с помощью ключевого слова if, после которого идет условие ограничения:
Здесь первый шаблон соответствует любому объекту Person, у которого атрибут age меньше 18. Собственно часть if age < 18 и представляет ограничение. Соответственно, если у пользователя возраст меньше 18, то будет выводьтся одно сообщение, если больше 18, то другое.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #guards #шаблоны
guards или ограничения шаблонов. Продолжение.
Подобным образом можно вводить дополнительные ограничения, первый пример:
Условия ограничений могут быть более сложными и составными по структуре, второй пример:
В данном случае функция получает кортеж data. Оба шаблона в конструкции match соответствуют двухэлементному кортежу. Но первый шаблон также применяет ограничение name == "admin" or age not in range(1, 101), в соответствии с которым первый элемент кортежа должен иметь значение "admin", а второй должен находиться вне диапазона 1-101.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #guards #шаблоны
Подобным образом можно вводить дополнительные ограничения, первый пример:
Условия ограничений могут быть более сложными и составными по структуре, второй пример:
В данном случае функция получает кортеж data. Оба шаблона в конструкции match соответствуют двухэлементному кортежу. Но первый шаблон также применяет ограничение name == "admin" or age not in range(1, 101), в соответствии с которым первый элемент кортежа должен иметь значение "admin", а второй должен находиться вне диапазона 1-101.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #guards #шаблоны
Установка псевдонимов и паттерн AS.
Оператор as позволяет установить псевдоним для значения шаблона или для всего шаблона. Простейший пример, смотрим пример:
Здесь первый шаблон соответствует трем строкам: "Tom" | "Tomas" | "Tommy". После набора значений идет оператор as, после которого указывается псевдоним. И вне зависимости от того, какая именно строка передана, она окажется в переменной name.
Псевдоним можно применять как для отдельного значения шаблона, так и для всего шаблона, вторая часть кода:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #паттерны #псевдонимы
Оператор as позволяет установить псевдоним для значения шаблона или для всего шаблона. Простейший пример, смотрим пример:
Здесь первый шаблон соответствует трем строкам: "Tom" | "Tomas" | "Tommy". После набора значений идет оператор as, после которого указывается псевдоним. И вне зависимости от того, какая именно строка передана, она окажется в переменной name.
Псевдоним можно применять как для отдельного значения шаблона, так и для всего шаблона, вторая часть кода:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #паттерны #псевдонимы
Установка псевдонимов и паттерн AS. Продолжение.
Обычно псевдонимы более применимы в каких-то более сложных по структуре данных. Например:
Здесь функция print_family принимает кортеж, который должен состоять из двух элементов Person. В первом шаблоне определяем для первого элемента псевдоним husband, а для второго - псевдоним wife. Затем, используя эти псевдонимы, мы можкем обращаться к их атрибутам.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #паттерны #псевдонимы
Обычно псевдонимы более применимы в каких-то более сложных по структуре данных. Например:
Здесь функция print_family принимает кортеж, который должен состоять из двух элементов Person. В первом шаблоне определяем для первого элемента псевдоним husband, а для второго - псевдоним wife. Затем, используя эти псевдонимы, мы можкем обращаться к их атрибутам.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #паттерны #псевдонимы
Pattern matching. Конструкция match.
Начиная с версии 3.10 в языке Python появилась такая функциональность как pattern matching (сопоставление шаблонов). Pattern matching представляет применение конструкции match, которая позволяет сопоставить выражение с некоторым шаблоном. И если выражение соответствует шаблону, то выполняются определенные действия. В этом смысле конструкция match похожа на конструкцию if/else/elif, которая выполняет определенные действия в зависимости от некоторого условия. Однако функциональность match гораздо шире - она также позволяет извлечь данные из составных типов и применить действия к различным частям объектов.
Конструкция match имеет следующее формальное определение:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Начиная с версии 3.10 в языке Python появилась такая функциональность как pattern matching (сопоставление шаблонов). Pattern matching представляет применение конструкции match, которая позволяет сопоставить выражение с некоторым шаблоном. И если выражение соответствует шаблону, то выполняются определенные действия. В этом смысле конструкция match похожа на конструкцию if/else/elif, которая выполняет определенные действия в зависимости от некоторого условия. Однако функциональность match гораздо шире - она также позволяет извлечь данные из составных типов и применить действия к различным частям объектов.
Конструкция match имеет следующее формальное определение:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
После ключевого слова match идет сравниваемое выражение. И затем после двоеточия на последующих строках располагаются выражения case. После каждого выражения case указывается шаблон, с которым сравнивается выражение из match. После шаблона через двоеточие указываются набор выполняемых действий блока case.
Конструкция match последовательно сравнивает выражение с шаблонами из блоков case. И если был найден шаблон из какого-нибудь блока case соответствует выражению из match, то выполняются инструкции из данного блока case.
В качестве паттернов/шаблонов, с которыми сравниваются выражения, могут применяться как данные примитивных типов, так и последовательности элементов и объектов классов.
Вначале рассмотрим ситуацию, когда в качестве шаблона выступают литералы примитивных типов. Например, в зависимости от языка выведем приветственное сообщение:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
После ключевого слова match идет сравниваемое выражение. И затем после двоеточия на последующих строках располагаются выражения case. После каждого выражения case указывается шаблон, с которым сравнивается выражение из match. После шаблона через двоеточие указываются набор выполняемых действий блока case.
Конструкция match последовательно сравнивает выражение с шаблонами из блоков case. И если был найден шаблон из какого-нибудь блока case соответствует выражению из match, то выполняются инструкции из данного блока case.
В качестве паттернов/шаблонов, с которыми сравниваются выражения, могут применяться как данные примитивных типов, так и последовательности элементов и объектов классов.
Вначале рассмотрим ситуацию, когда в качестве шаблона выступают литералы примитивных типов. Например, в зависимости от языка выведем приветственное сообщение:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
Здесь функция print_hello принимает параметр language, через который передается выбранный язык. В самой функции конструкция match сравнивает значение переменной language. В блоках case определяются шаблоны - строки, с которыми сопоставляется переменная language.
Например при вызове print_hello("english") параметр language равен "english", поэтому конструкция match выберет следующий блок case:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Здесь функция print_hello принимает параметр language, через который передается выбранный язык. В самой функции конструкция match сравнивает значение переменной language. В блоках case определяются шаблоны - строки, с которыми сопоставляется переменная language.
Например при вызове print_hello("english") параметр language равен "english", поэтому конструкция match выберет следующий блок case:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
Обратите внимание, что блоки case имеют отступы от начала конструкции match. А инструкции каждого блока case имеют отступы от начала данного блока case. Но если блок case имеет одну инстукцию, ее можно поместить на той же строке, что и оператор case:
Причем если выражение из match не соответствует ни одному из шаблонов case, то соответственно ни один из этих блоков case не выполняется.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Обратите внимание, что блоки case имеют отступы от начала конструкции match. А инструкции каждого блока case имеют отступы от начала данного блока case. Но если блок case имеет одну инстукцию, ее можно поместить на той же строке, что и оператор case:
Причем если выражение из match не соответствует ни одному из шаблонов case, то соответственно ни один из этих блоков case не выполняется.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
Если необходимо, чтобы при несовпадении значений (если ни один из шаблонов case не соответствует выражению match) выполнялись некоторые действия по умолчанию, то в этом случае применяется шаблон _ (прочерк):
Если ни один из шаблонов case не соответствует значению language, то будет выполняться блок, второй пример:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Если необходимо, чтобы при несовпадении значений (если ни один из шаблонов case не соответствует выражению match) выполнялись некоторые действия по умолчанию, то в этом случае применяется шаблон _ (прочерк):
Если ни один из шаблонов case не соответствует значению language, то будет выполняться блок, второй пример:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
Но также можно определить блок case, который позволяет сравнивать сразу с несколькими знечениями. В этом случае значения разделяются вертикальной чертой:
В данном случае шаблон case "american english" | "british english" | "english" соответствует сразу трем значениям.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Но также можно определить блок case, который позволяет сравнивать сразу с несколькими знечениями. В этом случае значения разделяются вертикальной чертой:
В данном случае шаблон case "american english" | "british english" | "english" соответствует сразу трем значениям.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Pattern matching. Конструкция match. Продолжение.
Подобным образом можно сравнивать выражения с данными других типов. Например:
Здесь функция operation принимает два числа и код операции. Конструкция match сравнивает код операции с конкретными значениями и в зависимости от значения выполняет на числами определенную операцию. Например, если code равен 1, то выполняется выражение, второй пример:
это выражение case возвратит из функцию сумму чисел a и b.
Аналогично если code = 2, то возвращается разность, а если code = 3, то возвращается произведение чисел. Во всех остальных случаях возвращается 0.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Подобным образом можно сравнивать выражения с данными других типов. Например:
Здесь функция operation принимает два числа и код операции. Конструкция match сравнивает код операции с конкретными значениями и в зависимости от значения выполняет на числами определенную операцию. Например, если code равен 1, то выполняется выражение, второй пример:
это выражение case возвратит из функцию сумму чисел a и b.
Аналогично если code = 2, то возвращается разность, а если code = 3, то возвращается произведение чисел. Во всех остальных случаях возвращается 0.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #конструкции #match
Кортежи в pattern matching.
В качестве шаблонов в pathern matching в Python могут выступать кортежи. Например:
В данном случае функция принимает параметр user, который, как предполагается, представляет кортеж из двух элементов. И конструкция match сравнивает этот кортеж с рядом шаблонов. Первый шаблон предполагает, что кортеж user точно соответствует набору значений, вторая маленькая часть кода:
То есть, если первый элемент кортежа равен "Tom", а второй - 37, то на консоль выводится строка "default user"
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи
В качестве шаблонов в pathern matching в Python могут выступать кортежи. Например:
В данном случае функция принимает параметр user, который, как предполагается, представляет кортеж из двух элементов. И конструкция match сравнивает этот кортеж с рядом шаблонов. Первый шаблон предполагает, что кортеж user точно соответствует набору значений, вторая маленькая часть кода:
То есть, если первый элемент кортежа равен "Tom", а второй - 37, то на консоль выводится строка "default user"
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи
Кортежи в pattern matching. Продолжение.
Второй шаблон соответствует любому двухэлементному кортежу, первый элемент которого равен строке "Tom":
Для второго элемента определяется переменная age. В итоге, если первый элемент кортежа равен строке "Tom", а второй не равен 37, то такой кортеж будет соответствовать второму шаблону. Причем второй элемент будет передаваться переменной age.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи
Второй шаблон соответствует любому двухэлементному кортежу, первый элемент которого равен строке "Tom":
Для второго элемента определяется переменная age. В итоге, если первый элемент кортежа равен строке "Tom", а второй не равен 37, то такой кортеж будет соответствовать второму шаблону. Причем второй элемент будет передаваться переменной age.
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи
Кортежи в pattern matching. Продолжение.
Третий шаблон во многом аналогичен, только теперь строго определен второй элемент кортежа - он должен быть равен 22, а первый попадает в переменную name:
Если двухэлементный кортеж не соответствует первому, второму и третьему шаблонам, то он будет соответствовать четвертому шаблону, в которому нам не важные конкретные значения - для них определены переменные name и age:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи
Третий шаблон во многом аналогичен, только теперь строго определен второй элемент кортежа - он должен быть равен 22, а первый попадает в переменную name:
Если двухэлементный кортеж не соответствует первому, второму и третьему шаблонам, то он будет соответствовать четвертому шаблону, в которому нам не важные конкретные значения - для них определены переменные name и age:
🐍 Укус питона // 💬 Чат // #теория #pattern_matching #кортежи