функции могут возвращать несколько параметров
Как вернуть сразу несколько значений из функции в Python 3
Сегодня мы делимся с вами переводом статьи, которую нашли на сайте medium.com. Автор, Vivek Coder, рассказывает о способах возврата значений из функции в Python и объясняет, как можно отличить друг от друга разные структуры данных.
Фото с сайта Unsplash. Автор: Vipul Jha
Python удобен в том числе тем, что позволяет одновременно возвращать из функции сразу несколько значений. Для этого нужно воспользоваться оператором return и вернуть структуру данных с несколькими значениями — например, список общего количества рабочих часов за каждую неделю.
Способ 1: возврат значений с помощью словарей
Словари содержат комбинации элементов, которые представляют собой пары «ключ — значение» ( key:value ), заключенные в фигурные скобки ( <> ).
Словари, на мой взгляд, это оптимальный вариант для работы, если вы знаете ключ для доступа к значениям. Далее представлен словарь, где ключом является имя человека, а соответствующим значением — возраст.
А теперь перейдем к функции, которая возвращает словарь с парами «ключ — значение».
Способ 2: возврат значений с помощью списков
Списки похожи на массивы, сформированные с использованием квадратных скобок, однако они могут содержать элементы разных типов. Списки также отличаются от кортежей, поскольку являются изменяемым типом данных. То есть любой список может меняться.
Списки — одна из наиболее универсальных структур данных в Python, потому что им не обязательно сохранять однородность (в них можно включать строки, числа и элементы). Иногда списки даже используют вместе со стеками или очередями.
Вот пример, где возвращается список с натуральными числами.
Способ 3: возврат значений с помощью кортежей
Кортежи — это упорядоченные неизменяемые объекты в Python, которые обычно используются для хранения коллекций неоднородных данных.
На этом примере кортеж используется для хранения данных о сотруднике (имя, опыт работы в годах и название компании).
А вот пример написания функции для возврата кортежа.
Не забывайте, что кортеж можно создать с помощью запятой вместо круглых скобок. Круглые скобки требуются только в тех случаях, когда используются пустые кортежи или вам нужно избежать синтаксической неточности.
Чтобы лучше разобраться в кортежах, обратитесь к официальной документации Python 3 (документация приведена на английском языке. — Прим. ред.).
Ниже показан пример функции, которая использует для возврата кортежа круглые скобки.
Повторюсь, кортежи легко перепутать со списками (в конце концов, и те, и другие представляют собой контейнер, состоящий из элементов). Однако нужно помнить о фундаментальном различии: кортежи изменить нельзя, а списки — можно.
Способ 4: возврат значений с помощью объектов
Тут все так же, как в C/C++ или в Java. Можно просто сформировать класс (в C он называется структурой) для сохранения нескольких признаков и возврата объекта класса.
Способ 5: возврат значений с помощью классов данных (Python 3.7+)
Классы данных в Python 3.7+ как раз помогают вернуть класс с автоматически добавленными уникальными методами, модулем typing и другими полезными инструментами.
Чтобы лучше разобраться в классах данных, обратитесь к официальной документации Python 3 (документация приведена на английском языке. — Прим. ред.).
Вывод
Цель этой статьи — ознакомить вас со способами возврата нескольких значений из функции в Python. И, как вы видите, этих способов действительно много.
Учите матчасть и постоянно развивайте свои навыки программирования. Спасибо за внимание!
Руководство по JavaScript, часть 4: функции
Сегодня публикуем четвёртую часть перевода руководства по JavaScript, которая посвящена функциям.
Функции в JavaScript
Поговорим о функциях в JavaScript, сделаем их общий обзор и рассмотрим подробности о них, знание которых позволит вам эффективно ими пользоваться.
Функция — это самостоятельный блок кода, который можно, один раз объявив, вызывать столько раз, сколько нужно. Функция может, хотя это и необязательно, принимать параметры. Функции возвращают единственное значение.
Кроме того, функции в JavaScript называют «функциями первого класса» так как их можно назначать переменным, их можно передавать другим функциям в качестве аргументов, их можно возвращать из других функций.
Сначала рассмотрим особенности работы с функциями и соответствующие синтаксические конструкции, которые существовали в языке до появления стандарта ES6 и актуальны до сих пор.
Вот как выглядит объявление функции (function declaration).
В наши дни такие функции называют «обычными», отличая их от «стрелочных» функций, которые появились в ES6.
Функцию можно назначить переменной или константе. Такая конструкция называется функциональным выражением (function expression).
Можно заметить, что в вышеприведённом примере функция назначена константе, но сама она имени не имеет. Такие функции называют анонимными. Подобным функциям можно назначать имена. В таком случае речь идёт об именованном функциональном выражении (named function expression).
Использование таких выражений повышает удобство отладки (в сообщениях об ошибках, где проводится трассировка стека, видно имя функции). Имя функции в функциональном выражении может понадобиться и для того, чтобы функция могла бы сама себя вызывать, без чего не обойтись при реализации рекурсивных алгоритмов.
В стандарте ES6 появились стрелочные функции (arrow function), которые особенно удобно использовать в виде так называемых «встроенных функций» (inline function) — в роли аргументов, передаваемых другим функциям (коллбэков).
Стрелочные функции, помимо того, что структуры, используемые для их объявления, получаются более компактными, чем при использовании обычных функций, отличаются от них некоторыми важными особенностями, о которых мы поговорим ниже.
Параметры функций
Параметры представляют собой переменные, которые задаются на этапе объявления функции и будут содержать передаваемые ей значения (эти значения называют аргументами). Функции в JavaScript могут либо не иметь параметров, либо иметь один или несколько параметров.
Здесь показано несколько примеров стрелочных функций.
Начиная со стандарта ES6 у функций могут быть так называемые «параметры по умолчанию» (default parameters).
Они представляют собой стандартные значения, задаваемые параметрам функций в том случае, если при её вызове значения некоторых параметров не задаются. Например, функцию, показанную выше, можно вызвать как с передачей ей всех двух принимаемых ей параметров, так и другими способами.
В ES8 появилась возможность ставить запятую после последнего аргумента функции (это называется trailing comma). Эта возможность позволяет повысить удобство редактирования кода при использовании систем контроля версий в ходе разработки программ. Подробности об этом можно почитать здесь и здесь.
Передаваемые функциям аргументы можно представлять в виде массивов. Для того чтобы разобрать эти аргументы можно воспользоваться оператором, который выглядит как три точки (это — так называемый «оператор расширения» или «оператор spread»). Вот как это выглядит.
Если функции нужно принимать много параметров, то запомнить порядок их следования может быть непросто. В таких случаях используются объекты с параметрами и возможности по деструктурированию объектов ES6.
Этот приём позволяет, описывая параметры в виде свойств объекта и передавая функции объект, получить в функции доступ к параметрам по их именам без использования дополнительных конструкций. Подробнее об этом приёме можно почитать здесь.
Значения, возвращаемые из функций
Если после ключевого слова return указать некое значение, то это значение возвращается в место вызова функции в качестве результата выполнения этой функции.
Из функции можно возвращать лишь одно значение. Для того чтобы получить возможность возврата нескольких значений, возвращать их можно либо в виде объекта, используя объектный литерал, либо в виде массива, а при вызове функции применять конструкцию деструктурирующего присваивания. Имена параметров при этом сохраняются. При этом, если нужно работать с объектом или массивом, возвращённым из функции, именно в виде объекта или массива, можно обойтись без деструктурирующего присваивания.
Конструкцию const [ name, age ] = doSomething() можно прочитать следующим образом: «объявить константы name и age и присвоить им значения элементов массива, который возвратит функция».
Вот как то же самое выглядит с использованием объекта.
Вложенные функции
Функции можно объявлять внутри других функций.
Область видимости вложенной функции ограничена внешней по отношению к ней функцией, её нельзя вызвать извне.
Методы объектов
Когда функции используются в качестве свойств объектов, такие функции называют методами объектов.
Ключевое слово this
Как видно, вызов метода start() приводит ко вполне ожидаемому результату, а вот метод stop() явно работает неправильно.
Вот как выглядит выполнение такого кода в консоли браузера.
Особенности ключевого слова this в обычных и стрелочных функциях
Всё это означает, что стрелочные функции не подходят на роль методов объектов и конструкторов (если попытаться использовать стрелочную функцию в роли конструктора — будет выдана ошибка TypeError ).
Немедленно вызываемые функциональные выражения
Немедленно вызываемое функциональное выражение (Immediately Invoked Function Expression, IIFE) — это функция, которая автоматически вызывается сразу после её объявления.
Точка с запятой перед IIFE необязательна, но её использование позволяет застраховаться от ошибок, связанных с автоматической расстановкой точек с запятой.
Поднятие функций
Если переместить вызов функции так, чтобы он шёл после её объявления, ничего не изменится.
Если же в похожей ситуации воспользоваться функциональным выражением, то похожий код выдаст ошибку.
Стрелочные функции
Сейчас мы подробнее поговорим о стрелочных функциях, с которыми мы уже встречались. Их можно считать одним из наиболее значительных новшеств стандарта ES6, они отличаются от обычных функций не только внешним видом, но и особенностями поведения. В наши дни они используются чрезвычайно широко. Пожалуй, нет ни одного современного проекта, где они не использовались бы в подавляющем большинстве случаев. Можно сказать, что их появление навсегда изменило и внешний вид JS-кода и особенности его работы.
С чисто внешней точки зрения синтаксис объявления стрелочных функций оказывается компактнее синтаксиса обычных функций. Вот объявление обычной функции.
Вот объявление стрелочной функции, которое, в целом, если не учитывать особенности стрелочных функций, аналогично предыдущему.
Как видите, параметры стрелочных функций, как и в случае с обычными функциями, описывают в скобках. При этом, если такая функция принимает всего один параметр, его можно указать без скобок. Например, вот функция, которая возвращает результат деления переданного ей числа на 2.
В результате оказывается, что стрелочные функции очень удобно использовать в ситуациях, в которых нужны маленькие функции.
▍Неявный возврат результатов работы функции
Мы уже касались этой особенности стрелочных функций, но она настолько важна, что её следует обсудить подробнее. Речь идёт о том, что однострочные стрелочные функции поддерживают неявный возврат результатов своей работы. Пример возврата примитивного значения из однострочной стрелочной функции мы уже видели. Как быть, если такая функция должна возвратить объект? В таком случае фигурные скобки объектного литерала могут запутать систему, поэтому в теле функции используются круглые скобки.
▍Ключевое слово this и стрелочные функции
Как мы уже видели, при использовании ключевого слова this в методе объекта, представленного обычной функцией, this указывает на объект, которому принадлежит метод. В таком случае говорят о привязке ключевого слова this к значению, представляющему собой контекст выполнения функции. В частности, если функция вызвана в виде метода объекта, то ключевое слово this привязано к этому объекту.
В случае же со стрелочными функциями оказывается так, что в них привязка this не выполняется, они пользуются ключевым словом this из содержащих их областей видимости. В результате их не рекомендуется использовать в качестве методов объектов.
Замыкания
Замыкания — это важная концепция в JavaScript. Фактически, если вы писали JS-функции, то вы пользовались и замыканиями. Замыкания применяются в некоторых паттернах проектирования — в том случае, если нужно организовать строгий контроль доступа к неким данным или функциям.
Когда функция вызывается, у неё есть доступ ко всему тому, что находится во внешней по отношению к ней области видимости. Но к тому, что объявлено внутри функции, извне доступа нет. То есть, если в функции была объявлена некая переменная (или другая функция), они недоступны внешнему коду ни во время выполнения функции, ни после завершения её работы. Однако если из функции возвратить другую функцию, то эта новая функция будет иметь доступ ко всему тому, что было объявлено в исходной функции. При этом всё это будет скрыто от внешнего кода в замыкании.
Рассмотрим пример. Вот функция, которая принимает имя собаки, после чего выводит его в консоль.
Значение, возвращаемое этой функцией нас пока не интересует, текст выводится в консоль с помощью IIFE, что в данном случае особой роли не играет, однако, это поможет нам увидеть связь между этой функцией и её вариантом, в котором, вместо вызова функции, которая выводит текст в консоль, мы эту функцию из переписанной функции bark() возвратим.
Результат работы код в двух случаях оказывается одинаковым. Но во втором случае то, что было передано исходной функции при её вызове (имя собаки, Roger ), хранится в замыкании, после чего используется другой функцией, возвращённой из исходной.
Проведём ещё один эксперимент — создадим, пользуясь исходной функцией, две новых, для разных собак.
Этот код выведет следующее.
Итоги
Уважаемые читатели! Как вы относитесь к стрелочным функциям в JavaScript?
Как я могу вернуть несколько значений из функции в C#?
прочитал C++ версия этого вопроса но на самом деле не понимал этого.
может кто-нибудь, пожалуйста, объяснить ясно, если это можно сделать и как?
25 ответов
кортежи с двумя значениями имеют Item1 и Item2 свойства.
теперь, когда c# 7 был выпущен, вы можете использовать новый синтаксис включенных кортежей
который можно было бы использовать следующим образом:
вы также можете предоставить имена своим элементам (поэтому они не являются «Item1», «Item2» и т. д.). Вы можете сделать это, добавив имя в подпись или методы возврата:
они также могут быть деконструированы, что является довольно приятной новой функцией:
проверить этой ссылке чтобы увидеть больше примеров того, что можно сделать 🙂
вы можете использовать три разных способа
1. номер модели / ref / out параметры
использование ref:
С помощью:
2. struct / class
использование struct:
использование класса:
3. Кортеж!—10—>
Кортеж класс!—10—>
Кортежи C# 7
вы не можете сделать это в C#. Что вы можете сделать, это иметь out parameter или верните свой собственный класс (или struct, если вы хотите, чтобы он был неизменяемым).
С помощью параметра Использование пользовательского класса (или структуры)
Если вы имеете в виду возврат нескольких значений, вы можете либо вернуть класс/структуру, содержащую значения, которые вы хотите вернуть, либо использовать ключевое слово «out» для ваших параметров, например:
предыдущий постер прав. Невозможно вернуть несколько значений из метода C#. Тем не менее, у вас есть несколько вариантов:
наконец, вы можете использовать выходные параметры, но я бы ограничил использование этого сценариями, когда у вас есть только пара (например, 3 или менее) параметры-в противном случае все становится уродливым и трудно поддерживать. Кроме того, использование выходных параметров может быть ингибитором гибкости, потому что ваша подпись метода должна будет меняться каждый раз, когда вам нужно добавить что-то к возвращаемому значению, тогда как возвращая экземпляр структуры или класса, вы можете добавлять члены без изменения подписи метода.
с архитектурной точки зрения я бы порекомендовал не использовать пары ключ-значение или словари. Я считаю, что этот стиль кодирования требует » секрет знание » в коде, который потребляет метод. Он должен заранее знать, какие ключи будут и что означают значения, и если разработчик, работающий над внутренней реализацией, изменит способ создания словаря или KVP, он может легко создать каскад сбоев во всем приложении.
вы либо вернуть экземпляр класса или использовать из параметры. Вот пример параметров:
есть несколько способов сделать это. Вы можете использовать ref параметры:
другой аналогичный подход заключается в использовании out параметр. Ан out параметр идентичен параметру ref параметр с дополнительным, принудительным правилом компилятора. Это правило заключается в том, что если вы передадите out параметр в функцию, эта функция должна установить свое значение до возвращения. Кроме этого правила, an
В C# 4, Вы сможете использовать встроенную поддержку для кортежей, чтобы легко справиться с этим.
тем временем, есть два варианта.
во-первых, вы можете использовать ref или out-параметры для присвоения значений параметров, которые возвращаются в вызывающую программу.
во-вторых, вы можете обернуть возвращаемые значения в структуру или класс и передать их обратно как члены этой структуры. KeyValuePair работает хорошо для 2-для более чем 2 вам понадобится пользовательский класс или структура.
нет, вы не можете возвращать несколько значений из функции в C# (для версий ниже C# 7), по крайней мере, не так, как вы можете это сделать в Python.
тем не менее, есть несколько альтернатив:
вы можете вернуть массив типа object с несколькими значениями, которые вы хотите в нем.
можно использовать out параметры.
В C#7 есть новый Tuple синтаксис:
вы можете вернуть эту запись:
вы также можете использовать новый синтаксис разрушитель:
Итак, для сериализации объявите класс записи и верните его вместо этого.
также новым в C#7 является улучшенный синтаксис для out параметры. Теперь вы можете объявить out inline, который лучше подходит в некоторых контекстах:
вы можете попробовать этот «KeyValuePair»
выход :
некоторые из этих ответов указано, что использовать out параметр но я рекомендую не использовать это из-за они не работают с async-методов. Видеть этой для получения дополнительной информации.
другие ответы, указанные с помощью кортежа, который я бы тоже рекомендовал, но используя новую функцию, представленную в C# 7.0.
классы, структуры, коллекции и массивы могут содержать несколько значений. Выходные и опорные параметры также могут быть установлены в функции. Возврат нескольких значений возможен в динамических и функциональных языках с помощью кортежей, но не в C#.
в основном существуют два метода. 1. Использовать параметры out / ref 2. Возвращает массив объектов
вот основные Two методы:
1) Использование ‘ out в качестве параметра Вы можете использовать » out » как для 4.0, так и для младших версий.
пример ‘out’:
выход:
площадь прямоугольника 20
периметр прямоугольника 18
2) Tuple
пример кортежа:
возврат нескольких значений типа данных с помощью Tuple
выход
метод, принимающий делегат, может предоставить вызывающему несколько значений. Это заимствует из моего ответа здесь и использует немного из принятый ответ Хадаса.
вызывающие объекты предоставляют лямбда (или именованную функцию), а intellisense помогает, копируя имена переменных из делегата.
просто используйте в ООП-манере такой класс:
член функции возвращает фактор, который интересует большинство вызывающих абонентов. Кроме того, он сохраняет остаток в качестве члена данных, который легко доступен вызывающему абоненту впоследствии.
таким образом, у вас может быть много дополнительных «возвращаемых значений», очень полезных при реализации вызовов базы данных или сети, где может потребоваться много сообщений об ошибках, но только в случае ошибки происходит.
Я ввел это решение также В вопрос C++, на который ссылается OP.
с этой статья, вы можете использовать три варианта, как указано выше.
KeyValuePair самый быстрый путь.
из на втором.
кортежа!—6—> самая медленная.
в любом случае, это зависит от того, что лучше для вашего сценария.
вы можете использовать динамический объект. Я думаю, что он имеет лучшую читаемость, чем Кортеж.
способы сделать это:
1) KeyValuePair (самое лучшее представление-0.32 ns):
3) из (1.64 НС) или Реф 4) Создайте свой собственный класс/структуру struct
будущая версия C# будет включать именованные кортежи. Посмотрите на эту сессию channel9 для демонстрации https://channel9.msdn.com/Events/Build/2016/B889
пропустить до 13: 00 для кортежа. Это позволит такие вещи, как:
Урок №13. Параметры и аргументы функций
Обновл. 11 Сен 2021 |
На предыдущем уроке мы говорили о том, что функция может возвращать значение обратно в caller, используя оператор return. На этом уроке мы узнаем, что такое аргументы в функции и что такое параметры в функции.
Параметры и аргументы функций
Во многих случаях нам нужно будет передавать данные в вызываемую функцию, чтобы она могла с ними как-то взаимодействовать. Например, если мы хотим написать функцию умножения двух чисел, то нам нужно каким-то образом сообщить функции, какие это будут числа. В противном случае, как она узнает, что на что перемножать? Здесь нам на помощь приходят параметры и аргументы.
Параметр функции — это переменная, которая используется в функции, и значение которой предоставляет caller (вызывающий объект). Параметры указываются при объявлении функции в круглых скобках. Если их много, то они перечисляются через запятую, например:
Аргумент функции — это значение, которое передается из caller-а в функцию и которое указывается в скобках при вызове функции в caller-е:
Обратите внимание, аргументы тоже перечисляются через запятую. Количество аргументов должно совпадать с количеством параметров, иначе компилятор выдаст сообщение об ошибке.
Как работают параметры и аргументы функций?
При вызове функции, все её параметры создаются как локальные переменные, а значение каждого из аргументов копируется в соответствующий параметр (локальную переменную). Этот процесс называется передачей по значению. Например:
Как работают параметры и возвращаемые значения функций?
Используя параметры и возвращаемые значения, мы можем создавать функции, которые будут принимать и обрабатывать данные, а затем возвращать результат обратно в caller.
Например, простая функция, которая принимает два целых числа и возвращает их сумму:
Результат выполнения программы:
Еще примеры
Рассмотрим еще несколько вызовов функций:
Результат выполнения программы:
С первыми двумя вызовами всё понятно.
Следующая пара относительно лёгкая для понимания:
Теперь рассмотрим вызов посложнее:
add(1, multiply(2, 3)) => add(1, 6) => 7
Последний вызов может показаться немного сложным из-за того, что параметром функции add() является другой вызов add():
add(1, add(2, 3)) => add(1, 5) => 6
Задание №1: Что не так со следующим фрагментом кода?
Задание №2: Какие здесь есть две проблемы?
Задание №3: Какой результат выполнения следующей программы?
Задание №4: Напишите функцию doubleNumber(), которая принимает целое число в качестве параметра, удваивает его, а затем возвращает результат обратно в caller.
Задание №5: Напишите полноценную программу, которая принимает целое число от пользователя (используйте std::cin), удваивает его с помощью функции doubleNumber() из предыдущего задания, а затем выводит результат на экран.
Ответы
Чтобы просмотреть ответ, кликните на него мышкой.
Ответ №1
Функция multiply() имеет тип возврата void, что означает, что эта функция не возвращает значения. Но, так как она все равно пытается возвратить значение с помощью оператора return, мы получим ошибку от компилятора. Функция должна иметь тип возврата int.
Ответ №2
Проблема №1: main() передает один аргумент в multiply(), но multiply() имеет два параметра.
Проблема №2: multiply() вычисляет результат и присваивает его локальной переменной, которую не возвращает обратно в main(). А поскольку тип возврата функции multiply() — int, то мы получим ошибку (в некоторых компиляторах) или неожиданные результаты (в остальных компиляторах).
Ответ №3