Share This
Связаться со мной
Крути в низ
Categories
//Скрытые сокровища Python

Скрытые сокровища Python

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

skrytye sokrovishha python d799838 - Скрытые сокровища Python

Перевод публикуется с сокращениями, автор оригинальной статьи Charudatta Manwatkar.

У меня появилось новое времяпрепровождение – чтение документации Python просто для удовольствия. Когда читаете что-то на досуге, вы склонны замечать интересные лакомые кусочки, которые могли пропустить. Итак, вот список лакомых кусочков, которые заставили меня подумать: «О! Вы можете сделать это на Python?»

1. Атрибуты функций

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

         def func(x):     intermediate_var = x**2 + x + 1      if intermediate_var % 2:         y = intermediate_var ** 3     else:         y = intermediate_var **3 + 1      # setting attributes here     func.optional_return = intermediate_var     func.is_awesome = 'Yes, my function is awesome.'      return y  y = func(3) print('Final answer is', y)  # Accessing function attributes print('Show calculations -->', func.optional_return) print('Is my function awesome? -->', func.is_awesome)     

Мы установили атрибуты optional_return и is_awesome в 10-й и 11-й строках соответственно, а также получили доступ к ним вне функции в строках 19 и 20. Вывод программы будет следующим:

         Final answer is 2197 Show calculations --> 13 Is my function awesome? --> Yes, my function is awesome.     

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

2. Цикл For-else

В Python вы можете добавить else в цикл for. Условие else будет срабатывать только в том случае, если во время выполнения в теле цикла не был обнаружен оператор break.

         my_list = ['some', 'list', 'containing', 'five', 'elements']  min_len = 3  for element in my_list:     if len(element) < min_len:         print(f'Caught an element shorter than {min_len} letters')         break else:     print(f'All elements at least {min_len} letters long')     
         All elements at least 3 letters long     

Обратите внимание, что здесь ни один элемент не имеет длины меньше 3, т. е. оператор break никогда не выполнится. Следовательно условие else будет срабатывать (после выполнения цикла for) и печатать показанный выше вывод.

Этого можно достичь с помощью отдельной переменной, которая отслеживает, был ли встречен оператор break. Не исключено, что это также будет менее запутанным для читающего ваш код человека. Добиться результата можно следующим образом:

         my_list = ['some', 'list', 'containing', 'five', 'elements']  min_len = 3  no_break = True for element in my_list:     if len(element) < min_len:         print(f'Caught an element shorter than {min_len} letters')         no_break = False         break  if no_break:     print(f'All elements at least {min_len} letters long')     

3. Разделители для INT

Трудно визуально различить целые числа, вроде 10000000 и 100000000. Мы не можем использовать здесь запятые, как в обычном (английском – прим. ред.) языке, потому что Python будет интерпретировать его как кортеж из нескольких целых чисел.

У Python есть очень удобный способ борьбы с этим: можно использовать подчеркивание в качестве разделителя для улучшения читабельности. Таким образом 1_000_000 будет интерпретироваться как целочисленное значение:

         a = 3250 b = 67_543_423_778  print(type(a)) print(type(b)) print(type(a)==type(b))     
         <class 'int'> <class 'int'> True     

4. eval() и exec()

Python имеет возможность динамически считывать строку и обрабатывать ее как часть программного кода. Это достигается с помощью функций eval() и exec() (eval предназначена для вычисления выражений, а exec – для выполнения операторов).

         a = 3  b = eval('a + 2') print('b =', b)  exec('c = a ** 2') print('c is', c)     
         b = 5 c is 9     

В строке 3 функция eval() считывает входную строку как выражение Python, вычисляет ее и присваивает результат переменной b. В строке 6 функция exec() считывает входную строку, как оператор Python и выполняет ее.

Вы даже можете передавать динамически созданные строки этим функциям. Например, можно создать 1000 переменных с именами x_0, x_1,…, x_999 без необходимости вручную записывать каждое из этих объявлений переменных в код. Кому-то подобный способ покажется совершенно бессмысленным, но это не так.

В более широком контексте программирования, а не только в Python, использование eval/exec дает крутой результат, потому что они позволяют писать динамический код, использующий доступную в рантайме информацию для решения проблем, которых может не быть при компиляции. Exec – это почти встроенный в Python интерпретатор. Если у вас есть трудная задача, один из способов решения – использовать именно его. Узнать больше об этих инструментах можно из другой статьи.

5. Ellipsis

Ellipsis или ... – это встроенная константа Python, аналогичная встроенным константам типа None, True, False и т. д. Она используется различными способами. Разберем некоторые.

5.1 Плейсхолдер

Подобно pass, Ellipsis может использоваться в качестве плейсхолдера, когда код не полностью написан, но требует некоторого заполнения:

         def some_function():     ...      def another_function():     pass     

5.2 Альтернатива «None»

None применяется, когда вы хотите обозначить пустой инпут или return, но иногда ни один из них не подходит, и в этом случае заполнителем может служить многоточие:

         # вычисление nth odd def nth_odd(n):     if isinstance(n, int):         return 2 * n - 1     else:         return None   # вычисление исходных данных n в nth odd def original_num(m=...):     if m is ...:         print('This function needs some input')     elif m is None:         print('Non integer input provided to nth_odd() function')     elif isinstance(m, int):         if m % 2:             print(f'{m} is {int((m + 1)/2)}th odd number')         else:             print(f'{m} is not an odd number')   original_num()  a = nth_odd(n='some string') original_num(a)  b = nth_odd(5) original_num(b)  original_num(16)     

Функция nth_odd() вычисляет энное нечетное число. Функция original_num() вычисляет исходное число n, учитывая энное нечетное число. Здесь None является одним из ожидаемых входных данных функции original_num(), поэтому мы не можем использовать его в качестве плейсхолдера по умолчанию для аргумента m. Вывод кода будет следующим:

         This function needs some input Non integer input provided to nth_odd() function 9 is 5th odd number 16 is not an odd number     

5.3 Нарезка массива в NumPy

NumPy использует многоточие для среза массива. Следующий код показывает два эквивалентных способа нарезки массива NumPy:

         import numpy as np  a = np.arange(16).reshape(2,2,2,2)  print(a[..., 0].flatten()) print(a[:, :, :, 0].flatten())     
         [ 0  2  4  6  8 10 12 14] [ 0  2  4  6  8 10 12 14]     

Таким образом ... сообщает о наличии стольких ‘:‘, сколько необходимо.

Заключение

В статье мы рассмотрели следующие интересные особенности, которые можно использовать в следующих целях:

  • атрибуты функций – для присваивания атрибутов функциям точно так же, как и объектам;
  • циклы for-else – для отслеживания того, был ли цикл выполнен без оператора break;
  • разделители int – для удобочитаемости больших целочисленных значений, вроде 32_534_478;
  • eval() и exec() – для считывания строковых значений как обычного кода Python с последующим запуском;
  • ellipsis – для применения универсальной встроенной константы.

Python – это не только полезный язык, но и весьма интересный. Мы все чем-то заняты в повседневной жизни, но это не должно нам мешать лучше изучить язык ради саморазвития. Удачи! Не останавливайтесь на достигнутом!

Дополнительные материалы:

  • ТОП-10 книг по Python: эффективно, емко, доходчиво
  • Как Python применяется в блокчейн
  • Парсинг сайтов на Python: подробный видеокурс и программный код
  • 10 советов о том, как научить ребенка программировать на Python
  • Python + Visual Studio Code = успешная разработка

  • 8 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close