Skip to content

Смотреть мир по-русски

Переведи английское сообщение для русских

Menu
Menu

Прекратите использовать неявные входы и выходы

Posted on 12/12/2022

Прекратите использовать неявные входы и выходы

Пообщайтесь с разработчиками Python достаточно долго, и вы узнаете все о Zen Of Python Тима Питера.

Zen , который вы можете легко прочитать , выполнив import this в Python REPL, представляет 19 из 20 руководящих принципов, лежащих в основе дизайна Python. Недавно я стал ценить один афоризм больше, чем другие: «Явное лучше, чем неявное».

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

Конечно, использование более подходящих имен переменных и замена магических чисел именованными константами (или, в случае Python, «константами») — это здорово. Но когда вы в последний раз выискивали неявные входные данные в своем коде и делали их явными?

✉️
Эта статья изначально была опубликована в моем информационном бюллетене Curious About Code . Никогда не пропустите проблему. Подпишитесь здесь →

Как распознать неявные входы и выходы

Сколько входов и выходов имеет следующая функция?

 def find_big_numbers(): with open("numbers.txt", "r") as f: for line in f: if line.strip().isnumeric(): number = float(line) if number > 100: print(number)

find_big_numbers() не имеет параметров и всегда возвращает None . Если бы вы не могли видеть тело функции и не могли получить доступ к стандартному потоку вывода , вы бы вообще поверили, что эта функция что-то делает?

И все же, find_big_numbers() имеет два входа и еще один выход, кроме None :

  • numbers.txt — это неявный ввод . Без него функция работать не будет, но без чтения тела функции узнать, что файл нужен, невозможно.
  • Магическое число 100 в строке 6 является неявным вводом . Вы не можете определить «большое число» без него, но нет способа узнать этот порог, не читая тело функции.
  • Значения могут выводиться или не выводиться на stdout , в зависимости от содержимого numbers.txt . Это неявный вывод , поскольку функция не возвращает эти значения.

Неявные результаты часто называют побочными эффектами .

Попробуй сам

Определите все входные и выходные данные функции is_adult в этом фрагменте кода:

 from datetime import date birthdays = { "miles": date(2000, 1, 14), "antoine": date(1987, 3, 25), "julia": date(2009, 11, 2), } children = set() adults = set() def is_adult(name): birthdate = birthdays.get(name) if birthdate: today = date.today() days_old = (today - birthdate).days years_old = days_old // 365 if years_old >= 18: print(f"{name} is an adult") adults.add(name) return True else: print(f"{name} is not an adult") children.add(name) return False
🤔
В этом коде больше неправильного, чем просто неявные вводы и выводы. Что бы вы еще сделали, чтобы очистить это?

Почему следует избегать неявного ввода и вывода

Одной из веских причин является их склонность нарушать принцип наименьшего удивления .

Конечно, не все неявные входы и выходы плохи. Такой метод, как .write() , который файловые объекты Python используют для записи данных в файл, имеет неявный вывод: файл. Нет никакого способа устранить это. Но это не удивительно. Запись в файл – это все.

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

💡
Это хорошее упражнение — прочитать код вашей любимой библиотеки на GitHub и посмотреть, сможете ли вы определить неявные и явные результаты. Спросите себя: кто-нибудь из них вас удивляет?

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

Как удалить неявный ввод и вывод

Вот снова find_big_numbers() , поэтому вам не нужно прокручивать вверх:

 def find_big_numbers(): with open("numbers.txt", "r") as f: for line in f: if line.strip().isnumeric(): number = float(line) if number > 100: print(number)

Ранее мы идентифицировали два неявных ввода, файл numbers.txt и число 100 , и один неявный вывод, значения, напечатанные в stdout . Давайте сначала поработаем над входными данными.

Вы можете переместить имя файла и пороговое значение в параметры функции:

 def find_big_numbers(path, threshold=100): with open(path, "r") as f: for line in f: if line.strip().isnumeric(): number = float(line) if number > threshold: print(number)

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

Но результат трудно проверить.

Если вы хотите знать, что функция выдала правильные значения, вам нужно перехватить stdout . Это возможно. Но почему бы просто не вернуть список всех значений:

 def find_big_numbers(path, threshold=100): big_numbers = [] with open(path, "r") as f: for line in f: if line.strip().isnumeric(): number = float(line) if number > threshold: big_numbers.append(number) return big_numbers

Теперь find_big_numbers() имеет явный оператор return , который возвращает список больших чисел, найденных в файле.

🤔
Помимо удаления неявного ввода и вывода, еще многое можно сделать для улучшения find_big_numbers() . Как бы вы его почистили?

Вы можете проверить find_big_numbers() , вызвав его с путем к файлу, содержимое которого известно, и сравнив возвращаемый список со списком правильных значений:

 # test_nums.txt looks like: # 29 # 375 # 84 >>> expected_nums = [375.0] >>> actual_nums = find_big_numbers("test_nums.txt") >>> assert(actual_nums == expected_nums)

find_big_numbers() теперь также более удобна для повторного использования. Вы не ограничены выводом чисел на stdout . Вы можете отправить эти большие числа, куда хотите.

🧠
Давайте резюмируем:

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

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

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

🤔
Итак, вот вопрос: удалили ли мы все неявные входные и выходные данные из find_big_numbers() ?

Любопытно, что случилось с 20-й строкой в ​​Zen of Python? В интернете гуляют всевозможные теории. Это кажется мне достаточно вероятным.

Узнайте больше о неявных вводах и выводах в превосходной книге Эрика Норманда Grokking Simplicity. Получите мгновенный доступ от Manning * или закажите его на Amazon *.

* Партнерская ссылка. Дополнительную информацию см. в раскрытии информации об аффилированных лицах .


Хотите больше подобного?

Одно электронное письмо каждую субботу с одним действенным советом.
Всегда меньше 5 минут вашего времени.

Подпишитесь сейчас

Обработка вашей заявки Отлично! Проверьте свой почтовый ящик и подтвердите подписку Произошла ошибка при отправке письма

  • A learning a day
  • A Smart Bear
  • AddyOsmani.com
  • AddyOsmani.com (AddyOsmani.com)
  • Adwyat Krishna
  • Alex Turek
  • All That is Solid
  • André Staltz
  • Ars Technica
  • arxivblog (arxivblog)
  • Atoms vs Bits
  • AVC
  • Basic Apple Guy
  • Ben Thompson
  • Benedict Evans
  • Blog – storytelling with data
  • Bob Nystrom
  • Built For Mars
  • Caleb Porzio
  • Christian Heilmann
  • Christopher C
  • Chun Tian (binghe)
  • Codrops
  • Cold Takes
  • Daily Infographic
  • Dan Luu
  • Daniel Lemire's blog
  • David Amos
  • David Perell
  • David Walsh Blog
  • Derek Sivers
  • Desvl
  • Devon's Site
  • Digital Inspiration
  • DKB Blog
  • dropsafe
  • DSHR
  • Dunk
  • DYNOMIGHT
  • eagereyes
  • Endless Metrics
  • Engadget
  • Engadget (Engadget)
  • Entitled Opinions
  • Exception Not Found
  • Experimental History
  • Farnam Street
  • Fed Guy
  • Felix Krause
  • Florent Crivello
  • FlowingData
  • FlowingData (FlowingData)
  • Free Mind
  • Full Stack Economics
  • Funny JS
  • Future A16Z
  • GeekWire (GeekWire)
  • Glassnode Insights
  • Hacker News Daily
  • Harvard Health
  • Human Who Codes
  • Hunter Walk
  • Infographics – Cool Infographics
  • Information is Beautiful
  • Irrational Exuberance
  • Jacob Kaplan-Moss
  • Jakob Greenfeld
  • James Sinclair
  • Jason Fried
  • Jeff Kaufman
  • Joel on Software
  • John Resig
  • John's internet house
  • Johnny Rodgers
  • Julia Evans
  • Julian.com
  • Kevin Cox
  • Kevin Norman
  • KK – Cool Tools
  • KK – Recomendo
  • KK – The Technium
  • Krishna
  • Laurence Gellert's Blog
  • Lee Robinson
  • Lines and Colors
  • Lyn Alden – Investment Strategy
  • Martin Fowler
  • Matt Might's blog
  • Mobilism Forums
  • More To That
  • Morgan Housel
  • My Super Secret Diary
  • NASA Astronomy Picture
  • Neckar's New Money
  • News Letter
  • Nick Whitaker
  • Nicky's New Shtuff
  • nutcroft
  • Paul Graham
  • Paul Graham: Essays
  • Penguin Random House
  • Philip Walton
  • Phoenix's island
  • Product Hunt
  • Prof Galloway
  • Psyche
  • Python Weekly
  • Quanta Magazine
  • Rachel
  • Real Life
  • Riccardo Mori
  • Sasha
  • Science & technology
  • Science current issue
  • Scott Hanselman's Blog
  • Sébastien Dubois
  • Secretum Secretorum
  • Seth's Blog
  • Shu Ding
  • Sidebar
  • SignalFire
  • SignalFire (SignalFire)
  • Simon Willison's Weblog
  • Simons Foundation
  • Singularity HUB
  • SLIME MOLD TIME MOLD
  • Slyar Home
  • Spencer Greenberg
  • Stay SaaSy
  • Stephen Malina
  • Strange Loop Canon
  • Stratechery
  • Tech Notes
  • TechCrunch
  • TechCrunch (TechCrunch)
  • The Commonplace
  • The Intrinsic Perspective
  • The Latest in Hearing Health | HeardThat
  • The Rabbit Hole
  • The Verge
  • TLDR Newsletter
  • Tom's blog
  • Tomasz Tunguz
  • Troy Hunt
  • Tychlog
  • Uncharted Territories
  • Visual Capitalist
  • Visual.ly (Visual.ly)
  • Visualising Data
  • Vitalik Buterin
  • Weichen Liu
  • What's New
  • Works in Progress
  • Workspaces
  • Writing
  • Xe's Blog
  • xkcd.com
  • xkcd.com (xkcd.com)
  • Yihui Xie
  • Zoran Jambor
  • АВК (AVC)
  • Адвиат Кришна (Adwyat Krishna)
  • Арс Техника (Ars Technica)
  • Астральный кодекс десять (Astral Codex Ten)
  • Астрономическая фотография НАСА (NASA Astronomy Picture)
  • Атлантический океан (The Atlantic)
  • безопасный (dropsafe)
  • Бенедикт Эванс (Benedict Evans)
  • Бесконечные показатели (Endless Metrics)
  • Билл Гейтс (Bill Gates)
  • Блог — сторителлинг с данными (Blog – storytelling with data)
  • Блог | Хранитель (Datablog | The Guardian)
  • Блог ДКБ (DKB Blog)
  • Блог Дэвида Уолша (David Walsh Blog)
  • Блог Дэниела Лемира (Daniel Lemire's blog)
  • Блокчейн (BlockChain)
  • Боковая панель (Sidebar)
  • Бретт Винтон (Brett Winton)
  • Будущее A16Z (Future A16Z)
  • Вайхен Лю (Weichen Liu)
  • Визуализация данных (Visualising Data)
  • Визуальный капиталист (Visual Capitalist)
  • Виталик Бутерин (Vitalik Buterin)
  • Внутренняя перспектива (The Intrinsic Perspective)
  • Все
  • Гарвардское здоровье (Harvard Health)
  • Грань (The Verge)
  • Дерек Сиверс (Derek Sivers)
  • Джейсон Фрайд (Jason Fried)
  • Джефф Кауфман (Jeff Kaufman)
  • Джулия Эванс (Julia Evans)
  • ДИНАМАЙТ (DYNOMIGHT)
  • Дуглас Вагетти (Douglas Vaghetti)
  • Дэвид Амос (David Amos)
  • Ежедневная инфографика (Daily Infographic)
  • Ежедневные новости хакеров (Hacker News Daily)
  • Еженедельник Питона (Python Weekly)
  • Журнал "Уолл Стрит (The Wall Street Journal)
  • Журнал Кванта (Quanta Magazine)
  • Записка Безумного Неда (The Mad Ned Memo)
  • Зоран Джамбор (Zoran Jambor)
  • Илон Маск (Elon Musk)
  • Интернет-дом Джона (John's internet house)
  • Инфографика – Классная инфографика (Infographics – Cool Infographics)
  • Информационный бюллетень TLDR (TLDR Newsletter)
  • Информация прекрасна (Information is Beautiful)
  • Иррациональное Изобилие (Irrational Exuberance)
  • Исключение не найдено (Exception Not Found)
  • Используйте (Make Use Of)
  • Ихуи Се (Yihui Xie)
  • Канал Дурова (Durov's Channel)
  • Кевин Кокс (Kevin Cox)
  • КК – крутые инструменты (KK – Cool Tools)
  • КК – Рекомендую (KK – Recomendo)
  • КК – Техниум (KK – The Technium)
  • Колоссальный (Colossal)
  • Кристиан Хайльманн (Christian Heilmann)
  • Кришна (Krishna)
  • Кроличья нора (The Rabbit Hole)
  • Кэти Вуд (Cathie Wood)
  • Лин Олден – Инвестиционная стратегия (Lyn Alden – Investment Strategy)
  • Линии и цвета (Lines and Colors)
  • Марк Гурман (Mark Gurman)
  • Мозговые выборки (Brain Pickings)
  • Мой супер секретный дневник (My Super Secret Diary)
  • Морган Хаузел (Morgan Housel)
  • Морской (Naval)
  • Наткрофт (nutcroft)
  • Наука & технологии (Science & technology)
  • Неизведанные территории (Uncharted Territories)
  • нетерпеливые глаза (eagereyes)
  • Никаких классификаций
  • Новостная рассылка (News Letter)
  • Новые деньги Неккара (Neckar's New Money)
  • Обучение в день (A learning a day)
  • Обыденность (The Commonplace)
  • Обычный яблочный парень (Basic Apple Guy)
  • Охотничья прогулка (Hunter Walk)
  • Параг Агравал (Parag Agrawal)
  • Перевод из твиттера
  • Подробнее об этом (More To That)
  • Поиск продукта (Product Hunt)
  • Полная экономика стека (Full Stack Economics)
  • Практичный разработчик (The Practical Developer)
  • Проф Галлоуэй (Prof Galloway)
  • Психея (Psyche)
  • Рабочие области (Workspaces)
  • Рабочие пространства (Workspaces)
  • Реальная жизнь (Real Life)
  • Риккардо Мори (Riccardo Mori)
  • Рэй Далио (Ray Dalio)
  • Рэйчел (Rachel)
  • Саша (Sasha)
  • Себастьен Дюбуа (Sébastien Dubois)
  • СЛАЙМ ПЛЕСЕНИ ВРЕМЯ ПЛЕСЕНИ (SLIME MOLD TIME MOLD)
  • Статистика стеклянных узлов (Glassnode Insights)
  • Стеф Смит (Steph Smith)
  • Стратехия (Stratechery)
  • Текущий выпуск науки (Science current issue)
  • Тим Кук (Tim Cook)
  • Томаш Тунгуз (Tomasz Tunguz)
  • Трой Хант (Troy Hunt)
  • Фонд Саймонса (Simons Foundation)
  • ХАБ Сингулярности (Singularity HUB)
  • Хакер Новости (Hacker News)
  • Хакер полдень (Hacker Noon)
  • Холодные приемы (Cold Takes)
  • Цифровое вдохновение (Digital Inspiration)
  • Что нового (What's New)
  • что твердо (All That is Solid)
  • Экономика полного стека (Full Stack Economics)
  • Экономист (The Economist)
  • Энономист (Enonomist)
  • Энономист Печать (Enonomist Print)
  • Якоб Гринфельд (Jakob Greenfeld)

твиттер

На вашем сайте нет Метки, поэтому здесь нечего показывать.

  • Февраль 2023
  • Январь 2023
  • Декабрь 2022
  • Ноябрь 2022
  • Октябрь 2022
  • Сентябрь 2022
  • Август 2022
  • Июль 2022
  • Июнь 2022
  • Май 2022
  • Апрель 2022
  • Март 2022
©2023 Смотреть мир по-русски | Design: Newspaperly WordPress Theme