Как можно получить помощь описание функции python
Перейти к содержимому

Как можно получить помощь описание функции python

  • автор:

Позволяет получить справку по любому объекту Python

Функция help() вызывает встроенную справочную систему. Эта функция предназначена для интерактивного использования.

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

Внимание:
Если в описании запрошенного объекта, в списке параметров появляется косая черта / , то это означает, что параметры до косой черты являются только позиционными.

Примеры получения справки по объектам Python.

>>> help() Welcome to Python 3.7.4 help utility. If this is your first time using Python, you should definitely check out the tutorial on the Internet at https://docs.python.org/3.7.4/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type "quit". To get a list of available modules, keywords, symbols, or topics, type "modules", "keywords", "symbols", or "topics". Each module also comes with a one-line summary of what it does; to list the modules whose name or summary contain a given string such as "spam", type "modules spam". help> 
>>> help(hash) Help on built-in function hash in module builtins: hash(obj, /) Return the hash value for the given object. Two objects that compare equal must also have the same hash value, but the reverse is not necessarily true. (END) 
>>> help(1) Help on int object: class int(object) | int(x=0) -> integer | int(x, base=10) -> integer | | Convert a number or string to an integer, or return 0 if no arguments | are given. If x is a number, return x.__int__(). For floating point | numbers, this truncates towards zero. | | If x is not a number or if base is given, then x must be a string, | bytes, or bytearray instance representing an integer literal in the | given base. The literal can be preceded by '+' or '-' and be surrounded | by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. | Base 0 means to interpret the base from the string as an integer literal. | >>> int('0b100', base=0) | 4 . . . 
  • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
  • Функция abs(), абсолютное значение числа
  • Функция all(), все элементы True
  • Функция any(), хотя бы один элемент True
  • Функция ascii(), преобразует строку в ASCII
  • Функция bin(), число в двоичную строку
  • Класс bool(), логическое значение объекта
  • Функция breakpoint(), отладчик кода
  • Класс bytearray(), преобразует в массив байтов
  • Класс bytes(), преобразует в строку байтов
  • Функция callable(), проверяет можно ли вызвать объект
  • Функция chr(), число в символ Юникода
  • Класс classmethod, делает функцию методом класса
  • Функция compile() компилирует блок кода Python
  • Класс complex(), преобразует в комплексное число
  • Функция delattr(), удаляет атрибут объекта
  • Класс dict() создает словарь
  • Функция dir(), все атрибуты объекта
  • Функция divmod(), делит числа с остатком
  • Функция enumerate(), счетчик элементов последовательности
  • Функция eval(), выполняет строку-выражение с кодом
  • Функция exec(), выполняет блок кода
  • Функция filter(), фильтрует список по условию
  • Класс float(), преобразует в вещественное число
  • Функция format(), форматирует значение переменной
  • Класс frozenset(), преобразует в неизменяемое множество
  • Функция getattr(), значение атрибута по имени
  • Функция globals(), переменные глобальной области
  • Функция hasattr(), наличие атрибута объекта
  • Функция hash(), хэш-значение объекта
  • Функция help(), справка по любому объекту
  • Функция hex(), число в шестнадцатеричную строку
  • Функция id(), идентификатор объекта
  • Функция input(), ввод данных с клавиатуры
  • Класс int(), преобразует в тип int
  • Функция isinstance(), принадлежность экземпляра к классу
  • Функция issubclass(), проверяет наследование класса
  • Функция iter(), создает итератор
  • Функция len(), количество элементов объекта
  • Класс list(), преобразовывает в список
  • Функция locals(), переменные локальной области
  • Функция map(), обработка последовательности без цикла
  • Функция max(), максимальное значение элемента
  • Класс memoryview(), ссылка на буфер обмена
  • Функция min(), минимальное значение элемента
  • Функция next(), следующий элемент итератора
  • Класс object(), возвращает безликий объект
  • Функция oct(), число в восьмеричную строку
  • Функция open(), открывает файл на чтение/запись
  • Функция ord(), число символа Unicode
  • Функция pow(), возводит число в степень
  • Функция print(), печатает объект
  • Класс property(), метод класса как свойство
  • Класс range(), генерирует арифметические последовательности
  • Функция repr(), описание объекта
  • Функция reversed(), разворачивает последовательность
  • Функция round(), округляет число
  • Класс set(), создает или преобразовывает в множество
  • Функция setattr(), создает атрибут объекта
  • Класс slice(), шаблон среза
  • Функция sorted(), выполняет сортировку
  • Декоратор staticmethod(), метод класса в статический метод
  • Класс str(), преобразует объект в строку
  • Функция sum(), сумма последовательности
  • Функция super(), доступ к унаследованным методам
  • Класс tuple(), создает или преобразует в кортеж
  • Класс type(), возвращает тип объекта
  • Функция vars(), словарь переменных объекта
  • Функция zip(), объединить элементы в список кортежей
  • Функция __import__(), находит и импортирует модуль
  • Функция aiter(), создает асинхронный итератор
  • Функция anext(), следующий элемент асинхронного итератора

ХОЧУ ПОМОЧЬ
ПРОЕКТУ

Как сделать документацию к функции?

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

Чтобы создать описание функции, внутри функции перед её телом нужно сделать многострочный комментарий(делается он с помощью трёх знаков »’ ). Этот комментарий будет рассматриваться, как аттрибут .__doc__ и будет появляться при вызове help() , но об этом чуть позже.

Давайте сделаем небольшую функцию:

def to_str_smth(smth, step=1): smth = str(smth) return smth[::step] 

Функция есть, давайте сделаем к ней описание для тех, кто будет, например, импортировать модуль с ней.

def to_str_smth(smth, step=1): """ to_str_smth(smth, step=1) Makes the input data string and return it sliced with step """ smth = str(smth) return smth[::step] 

Теперь вызовем нашу документацию:

print(to_str_smth.__doc__) 

Документацию можно вызвать и с помощью команды help(), но тогда свернётся весь наш аутпут и откроется что-то типа подокна (если вы знакомы с редактором nano, то вам будет проще понять), из которого можно выйти, нажав q

help(to_str_smth) 

Почему не вызывем документацию у to_str_smth(), указывая скобки? Потому что так функция затребует аргументы, если они обязательны. К тому же, таким образом мы можем вернуть документацию подфункции, если она указана в return.

Посмотрим, например, на эту функцию:

def plus(a, b): """ plus(a, b) Return a + b, typed float """ return float(a + b) 

Давайте попробуем вывести на экран документацию для неё, указав скобки:

print(plus().__doc__) 

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

print(plus(2.3, 2.7).__doc__) 

Не совсем то, что хотелось бы видеть.

Важно соблюдать одинаковое форматирование при написании документации, как и при написании кода. Ознакомиться с рекомендациями по тому, как стоит документировать функции и классы, можно в справке PEP257. Кстати, всё, что заключённо между парой »’ игнорируется интерпретатором и таким образом можно спрятать блоки кода при его тестах.

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

Сделать это можно следующим образом (подразумевается, что запуск идёт из директории с модулем):

pydoc3.6 -w ./mymodule # также подойдёт pydoc -w ./mymodule.py 

Таким образом будет создан html файл с вашей документацией для модуля mymodule. Дизайн не очень, зато быстро. Для стартапов пойдёт. К тому же, помимо pydoc есть множество программ, которые генерируют документацию в файл. Вот некоторые из них:

Обращаясь к документации с помощью help() или .__doc__ , мы можем разрешить множество вопросов, связанных с импортируемыми модулями, а документируя свой код — не забыть что он делает, возвращает и для чего он нужен спустя долгое время.

Как сделать функции на Python еще лучше

Собственно, заголовок этой замечательной статьи от Джеффа Кнаппа (Jeff Knupp), автора книги «Writing Idiomatic Python» полностью отражает ее суть. Читайте внимательно и не стесняйтесь комментировать.

Поскольку очень не хотелось оставлять в тексте важный термин латиницей, мы позволили себе перевести слово «docstring» как «докстрока», обнаружив этот термин в нескольких русскоязычных источниках.

В Python, как и в большинстве современных языков программирования, функция – это основной метод абстрагирования и инкапсуляции. Вы, будучи разработчиком, вероятно, написали уже сотни функций. Но функции функциям – рознь. Причем, если писать «плохие» функции, это немедленно скажется на удобочитаемости и поддержке вашего кода. Итак, что же такое «плохая» функция, а еще важнее – как сделать из нее «хорошую»?

Освежим тему

Математика изобилует функциями, правда, припомнить их сложно. Так что давайте вернемся к нашей излюбленной дисциплине: анализу. Вероятно, вам доводилось видеть формулы вроде f(x) = 2x + 3 . Это функция под названием f , принимающая аргумент x , а затем «возвращающая» дважды x + 3 . Хотя, она и не слишком похожа на те функции, к которым мы привыкли в Python, она совершенно аналогична следующему коду:

def f(x): return 2*x + 3

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

Секреты хорошей функции

Что отличает «хорошую» функцию Python от посредственной? Вы удивитесь, как много трактовок допускает слово «хорошая». В рамках этой статьи я буду считать функцию Python «хорошей», если она удовлетворяет большинству пунктов из следующего списка (выполнить все пункты для конкретной функции порой невозможно):

  • Она внятно названа
  • Соответствует принципу единственной обязанности
  • Содержит докстроку
  • Возвращает значение
  • Состоит не более чем из 50 строк
  • Она идемпотентная и, если это возможно, чистая

Вот моя любимая цитата на эту тему, часто ошибочно приписываемая Дональду, а на самом деле принадлежащая Филу Карлтону:

В компьютерных науках есть две сложности: инвалидация кэша и именование.

Как бы глупо это ни звучало, именование – действительно сложная штука. Вот пример «плохого» названия функции:

def get_knn_from_df(df):

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

Первая проблема с названием этой функции – в нем используются аббревиатуры. Лучше использовать полные английские слова, а не аббревиатуры и не малоизвестные сокращения. Единственная причина, по которой хочется сокращать слова — не тратить сил на набор лишнего текста, но в любом современном редакторе есть функция автозавершения, поэтому вам придется набрать полное название функции всего один раз. Аббревиатура – это проблема, поскольку зачастую она специфична для предметной области. В вышеприведенном коде knn означает «K-ближайшие соседи», а df означает «DataFrame», структуру данных, повсеместно используемую в библиотеке pandas. Если код будет читать программист, не знающий этих сокращений, то он практически ничего не поймет в названии функции.

Еще в названии этой функции есть два более мелких недочета. Во-первых, слово «get» избыточно. В большинстве грамотно поименованных функций сразу понятно, что данная функция что-то возвращает, что конкретно – отражено в имени. Элемент from_d f также не нужен. Либо в докстроке функции, либо (если она находится на периферии) в аннотации типа будет описан тип параметра, если эта информация и так не очевидна из названия параметра.

Так как же нам переименовать эту функцию? Просто:

def k_nearest_neighbors(dataframe):

Теперь даже неспециалисту понятно, что вычисляется в этой функции, а имя параметра (dataframe) не оставляет сомнений, какой аргумент ей следует передавать.

Единственная ответственность

Развивая мысль Боба Мартина, скажу, что Принцип единственной ответственности касается функций не меньше, чем классов и модулей (о которых изначально и писал господин Мартин). Согласно этому принципу (в нашем случае) у функции должна быть единственная ответственность. То есть, она должна делать одну и только одну вещь. Один из самых веских доводов в пользу этого: если функция делает всего одну вещь, то и переписывать ее придется в единственном случае: если эту самую вещь придется делать по-новому. Также становится ясно, когда функцию можно удалить; если, внеся изменения где-то в другом месте, мы поймем, что единственная обязанность функции более не актуальна, то мы от нее просто избавимся.

Здесь лучше привести пример. Вот функция, делающая более одной «вещи»:

def calculate_and print_stats(list_of_numbers): sum = sum(list_of_numbers) mean = statistics.mean(list_of_numbers) median = statistics.median(list_of_numbers) mode = statistics.mode(list_of_numbers) print('-----------------Stats-----------------') print('SUM: <>'.format(sum) print('MEAN: <>'.format(mean) print('MEDIAN: <>'.format(median) print('MODE: <>'.format(mode)

А именно две: вычисляет набор статистических данных о списке чисел и выводит их в STDOUT . Функция нарушает правило: должна быть единственная конкретная причина, по которой ее, возможно, потребовалось бы изменить. В данном случае просматриваются две очевидные причины, по которым это понадобится: либо потребуется вычислять новую или иную статистику, либо потребуется изменить формат вывода. Поэтому данную функцию лучше переписать в виде двух отдельных функций: одна будет выполнять вычисления и возвращать их результаты, а другая – принимать эти результаты и выводить их в консоль. Функцию (вернее, наличие у нее двух обязанностей) с потрохами выдает слово and в ее названии.

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

На самом деле, функции, выполняющие ровно две вещи, встречаются редко. Гораздо чаще натыкаешься на функции, делающие намного, намного больше операций. Опять же, из соображений удобочитаемости и тестируемости такие «многостаночные» функции следует дробить на однозадачные, в каждой из которых заключен единственный аспект работы.

Докстроки

Казалось бы, все в курсе, что есть документ PEP-8, где даются рекомендации по стилю кода на Python, но гораздо меньше среди нас тех, кто знает PEP-257, в котором такие же рекомендации даются по поводу докстрок. Чтобы не пересказывать содержание PEP-257, отсылаю вас самих к этому документу – почитайте в свободное время. Однако, основные его идеи таковы:

  • Для каждой функции нужна докстрока
  • В ней следует соблюдать грамматику и пунктуацию; писать законченными предложениями
  • Докстрока начинается с краткого (в одно предложение) описания того, что делает функция
  • Докстрока формулируется в предписывающем, а не в описательном стиле

Возвращаемые значения

Функции можно (и следует) трактовать как маленькие самодостаточные программы. Они принимают некоторый ввод в форме параметров и возвращают результат. Параметры, конечно, опциональны. А вот возвращаемые значения обязательны с точки зрения внутреннего устройства Python. Если вы даже попытаетесь написать функцию, которая не возвращает значения – не сможете. Если функция даже не станет возвращать значения, то интерпретатор Python «принудит» ее возвращать None . Не верите? Попробуйте сами:

❯ python3 Python 3.7.0 (default, Jul 23 2018, 20:22:55) [Clang 9.1.0 (clang-902.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> def add(a, b): . print(a + b) . >>> b = add(1, 2) 3 >>> b >>> b is None True

Как видите, значение b – по сути None . Итак, даже если вы напишете функцию без инструкции return, она все равно будет что-то возвращать. И должна. В конце концов, это ведь маленькая программа, верно? Насколько полезны программы, от которых нет никакого вывода – и поэтому невозможно судить, верно ли выполнилась данная программа? Но самое важное – как вы собираетесь тестировать такую программу?

Я даже не побоюсь утверждать следующее: каждая функция должна возвращать полезное значение, хотя бы ради тестируемости. Код, который я пишу, должен быть протестирован (это не обсуждается). Только представьте, каким корявым может получится тестирование вышеприведенной функции add (подсказка: вам придется перенаправлять ввод/вывод, после чего вскоре все пойдет наперекосяк). Кроме того, возвращая значение, мы можем выполнять сцепление методов и, следовательно, писать код вот так:

with open('foo.txt', 'r') as input_file: for line in input_file: if line.strip().lower().endswith('cat'): # . делаем с этими строками что-нибудь полезное

Строка if line.strip().lower().endswith(‘cat’): работает, поскольку каждый из строковых методов ( strip() , lower() , endswith() ) в результате вызова функции возвращает строку.

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

«Она всего лишь [какая-то операция, связанная с вводом/выводом, например, сохранение значения в базе данных]. Здесь я не могу вернуть ничего полезного.»

Не соглашусь. Функция может вернуть True, если операция завершилась успешно.

«Здесь мы изменяем один из имеющихся параметров, используем его как ссылочный параметр.»»»

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

«Мне нужно возвращать несколько значений. Нет такого единственного значения, которое в данном случае было бы целесообразно возвращать.»

Этот аргумент немного надуманный, но мне доводилось его слышать. Ответ, разумеется, как раз в том, что автор и хотел сделать – но не знал как: для возврата нескольких значений используйте кортеж.

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

Длина функции

Я не раз признавался, что довольно туп. Могу одновременно держать в голове примерно три вещи. Если вы дадите мне прочесть 200-строчную функцию и спросите, что она делает, я, вероятно, буду таращиться на нее не менее 10 секунд. Длина функции прямо сказывается на ее удобочитаемости и, следовательно, на поддержке. Поэтому старайтесь, чтобы ваши функции оставались короткими. 50 строк – величина, взятая совершенно с потолка, но мне она кажется разумной. (Надеюсь), что большинство функций, которые вам доведется писать, будут значительно короче.

Если функция соответствует Принципу единственной ответственности, то, вероятно, она будет достаточно краткой. Если она читая или идемпотентная (об этом мы поговорим) ниже – то, наверное, она также получится короткой. Все эти идеи гармонично сочетаются друг с другом и помогают писать хороший, чистый код.

Итак, что же делать, если ваша функция получилась слишком длинной? РЕФАКТОРИТЬ! Вероятно, вам приходится заниматься рефакторингом постоянно, даже если вы не знаете этого термина. Рефакторинг – это попросту изменение структуры программы, без изменения ее поведения. Поэтому, извлечение нескольких строк кода из длинной функции и превращение их в самостоятельную функцию – это один из типов рефакторинга. Оказывается, это еще и наиболее распространенный, и самый быстрый способ продуктивного укорачивания длинных функций. Поскольку вы даете этим новым функциям подходящие имена, получающийся у вас код гораздо проще читать. Я написал целую книгу о рефакторинге (на самом деле, я им постоянно занимаюсь), так что здесь вдаваться в детали не буду. Просто знайте, что, если у вас есть слишком длинная функция – то ее следует рефакторить.

Идемпотентность и функциональная чистота

Заголовок этого раздела может показаться слегка устрашающим, но концептуально раздел прост. Идемпотентная функция при одинаковом наборе аргументов всегда возвращает одно и то же значение, независимо от того, сколько раз ее вызывают. Результат не зависит от нелокальных переменных, изменяемости аргументов или от любых данных, поступающих из потоков ввода/вывода. Следующая функция add_three(number) идемпотентна:

def add_three(number): """вернуть *число* + 3.""" return number + 3

Независимо от того, сколько раз мы вызовем add_three(7) , ответ всегда будет равен 10. А вот другой случай – функция, не являющаяся идемпотентной:

def add_three(): """Вернуть 3 + число, введенное пользователем.""" number = int(input('Enter a number: ')) return number + 3

Эта откровенно надуманная функция не идемпотентна, поскольку возвращаемое значение функции зависит от ввода/вывода, а именно – от числа, введенного пользователем. Разумеется, при разных вызовах add_three() возвращаемые значения будут отличаться. Если мы дважды вызовем эту функцию, то пользователь в первом случае может ввести 3, а во втором – 7, и тогда два вызова add_three() вернут 6 и 10 соответственно.

Вне программирования также встречаются примеры идемпотентности – например, по такому принципу устроена кнопка «вверх» у лифта. Нажимая ее в первый раз, мы «уведомляем» лифт, что хотим подняться. Поскольку кнопка идемпотентна, то сколько ее потом ни нажимать – ничего страшного не произойдет. Результат будет всегда одинаков.

Почему идемпотентность так важна

Тестируемость и удобство в поддержке. Идемпотентные функции легко тестировать, поскольку они гарантированно, в любом случае вернут одинаковый результат, если вызвать их с одними и теми же аргументами. Тестирование сводится к проверке того, что при разнообразных вызовах функция всегда возвращает ожидаемое значение. Более того, эти тесты будут быстрыми: скорость тестов – важная проблема, которую часто обходят вниманием при модульном тестировании. А рефакторинг при работе с идемпотентными функциями – вообще легкая прогулка. Не важно, как вы измените код вне функции – результат ее вызова с одними и теми же аргументами всегда будет один и тот же.

Что такое «чистая» функция?

В функциональном программировании функция считается чистой, если она, во-первых, идемпотентна, а во-вторых – не вызывает наблюдаемых побочных эффектов. Не забывайте: функция идемпотентна, если всегда возвращает один и тот же результат при конкретном наборе аргументов. Однако, это не означает, что функция не может влиять на другие компоненты – например, на нелокальные переменные или потоки ввода/вывода. Например, если бы идемпотентная версия вышеприведенной функции add_three(number) выводила результат в консоль, а лишь затем возвращала бы его, она все равно считалась бы идемпотентной, поскольку при ее обращении к потоку ввода/вывода эта операция доступа никак не влияет на значение, возвращаемое от функции. Вызов print() – это просто побочный эффект: взаимодействие с остальной программой или системой как таковой, происходящее наряду с возвратом значения.

Давайте немного разовьем наш пример с add_three(number) . Можно написать следующий код, чтобы определить, сколько раз была вызвана add_three(number) :

add_three_calls = 0 def add_three(number): """Вернуть *число* + 3.""" global add_three_calls print(f'Returning ') add_three_calls += 1 return number + 3 def num_calls(): """Вернуть, сколько раз была вызвана *add_three*.""" return add_three_calls

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

Чистая функция не оказывает побочных эффектов. Она не только не использует никаких «внешних данных» при расчете значения, но и не взаимодействует с остальной программой/системой, только вычисляет и возвращает указанное значение. Следовательно, хотя наше новое определение add_three(number) остается идемпотентным, эта функция уже не чистая.

В чистых функциях нет инструкций логирования или вызовов print() . При работе они не обращаются к базе данных и не используют соединений с интернетом. Не обращаются к нелокальным переменным и не изменяют их. И не вызывают других не-чистых функций.

Короче говоря, они не оказывают «жуткого дальнодействия», выражаясь словами Эйнштейна (но в контексте информатики, а не физики). Они не изменяют каким-либо образом остальные части программы или системы. В императивном программировании (а именно им вы и занимаетесь, когда пишете код на Python), такие функции – самые безопасные. Они известны своей тестируемостью и удобством в поддержке; более того, поскольку они идемпотентны, тестирование таких функций гарантированно будет столь же быстрым, как и выполнение. Сами тесты также просты: не приходится подключаться к базе данных либо имитировать какие-либо внешние ресурсы, готовить стартовую конфигурацию кода, а по окончании работы не нужно ничего подчищать.

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

Заключение

Вот и все. Оказывается, секрет создания новых функций – никакой не секрет. Просто нужно придерживаться некоторых выверенных наилучших практик и железных правил. Надеюсь, статья вам понравилась. А теперь идите – и перескажите ее друзьям! Давайте договоримся везде и во всех случаях писать отличный код. Или, как минимум, прилагать максимум усилий, чтобы не плодить в этом мире «плохой код». С этим я смогу жить.

  • python
  • чистый код
  • функциональное программирование
  • Блог компании Издательский дом «Питер»
  • Python
  • Программирование
  • Функциональное программирование

Встроенная функция для вывода всех текущих свойств и значений объекта в Python

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

Алексей Кодов
Автор статьи
7 июля 2023 в 17:40

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

class MyClass: def __init__(self, value1, value2): self.property1 = value1 self.property2 = value2 my_object = MyClass(10, 20)

В данном случае хотелось бы вывести на экран все свойства объекта my_object и их значения.

В языке программирования Python нет встроенной функции, аналогичной функции print_r в PHP, однако есть несколько способов, которые могут помочь в решении этой задачи.

Использование функции vars

Функция vars в Python возвращает словарь, который содержит атрибуты данного объекта.

print(vars(my_object))

Результат выполнения этого кода может выглядеть следующим образом:

Использование функции dir

Функция dir в Python возвращает список имен атрибутов объекта.

print(dir(my_object))

Однако, функция dir возвращает все атрибуты, включая служебные методы класса, что может быть избыточно. Но с ее помощью можно получить список всех атрибутов объекта, а затем получить их значения.

for attribute_name in dir(my_object): attribute_value = getattr(my_object, attribute_name) print(f': ')

Использование модуля pprint

Если объект содержит сложную структуру, то его может быть сложно отображать с помощью обычного print . В этом случае на помощь приходит модуль pprint (pretty-print), который предоставляет возможности для более красивого вывода данных.

import pprint pprint.pprint(vars(my_object))

Важно помнить, что эти функции могут не всегда работать с некоторыми типами объектов, например, встроенными типами данных, такими как списки или словари.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *