Это питон для функции, чтобы вернуть несколько значений?
в python функция может возвращать несколько значений. Вот надуманный пример:
def divide(x, y):
quotient = x/y
remainder = x % y
return quotient, remainder
(q, r) = divide(22, 7)
это кажется очень полезным, но похоже, что им также можно злоупотреблять ("Ну..функция X уже вычисляет то, что нам нужно в качестве промежуточного значения. Пусть X также вернет это значение").
когда вы должны нарисовать линию и определить другой метод?
9 ответов:
абсолютно (для примера вы указали).
кортежи являются гражданами первого класса в Python
есть встроенная функция
divmod()что делает именно это.q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == xесть и другие примеры:
zip,enumerate,dict.items.for i, e in enumerate([1, 3, 3]): print "index=%d, element=%s" % (i, e) # reverse keys and values in a dictionary d = dict((v, k) for k, v in adict.items()) # or d = dict(zip(adict.values(), adict.keys()))кстати, скобки не нужны большую часть времени. Цитата из Ссылка На Библиотеку Python:
кортежи могут быть построены в a количество способов:
- используя пару скобок для обозначения пустого кортежа: ()
- использование конечной запятой для одноэлементного кортежа: a, или (a,)
- разделение элементов запятыми: a, b, c или (a, b, c)
- С помощью кортежа () встроенный: кортеж () или кортеж(iterable)
функции должны служить одной цели
поэтому они должны возвращать один объект. В вашем случае этот объект это кортеж. Рассмотрим кортеж как специальную составную структуру данных. Есть языки, где почти каждая функция возвращает несколько значений (список в Лиспе).
иногда достаточно вернуться
(x, y)вместоPoint(x, y).именованных кортежей
С введением именованных кортежей в Python 2.6 во многих случаях предпочтительно возвращать именованные кортежи вместо простых кортежей.
>>> import collections >>> Point = collections.namedtuple('Point', 'x y') >>> x, y = Point(0, 1) >>> p = Point(x, y) >>> x, y, p (0, 1, Point(x=0, y=1)) >>> p.x, p.y, p[0], p[1] (0, 1, 0, 1) >>> for i in p: ... print(i) ... 0 1
во-первых, обратите внимание, что Python позволяет следующее (Нет необходимости в скобках):
q, r = divide(22, 7)что касается вашего вопроса, нет никаких жестких правил в любом случае. Для простых (и обычно надуманных) примеров может показаться, что для данной функции всегда возможно иметь одну цель, что приводит к одному значению. Однако при использовании Python для реальных приложений вы быстро сталкиваетесь со многими случаями, когда необходимо возвращать несколько значений и приводит к более чистый код.
Итак, я бы сказал, Делайте все, что имеет смысл, и не пытайтесь соответствовать искусственной конвенции. Python поддерживает несколько возвращаемых значений, поэтому использовать его при необходимости.
пример, который вы даете, на самом деле является встроенной функцией python, называемой
divmod. Так что кто-то, в какой-то момент, казалось, что достаточно подходящие для Python, чтобы включить в базовую функциональность.для меня, если это делает код чище, это питон. Сравните эти два блока кода:
seconds = 1234 minutes, seconds = divmod(seconds, 60) hours, minutes = divmod(minutes, 60) seconds = 1234 minutes = seconds / 60 seconds = seconds % 60 hours = minutes / 60 minutes = minutes % 60
да, возвращая несколько значений (т. е. кортеж), безусловно, питон. Как указывали другие, есть много примеров в стандартной библиотеке Python, а также в уважаемых проектах Python. Два дополнительных комментария:
- возврат нескольких значений иногда очень, очень полезно. Возьмем, например, метод, который необязательно обрабатывает событие (возвращая при этом некоторое значение), а также возвращает успех или неудачу. Это может возникнуть в цепочке модель ответственности. В других случаях вы хотите вернуть несколько тесно связанных фрагментов данных-как в приведенном примере. В этом параметре возврат нескольких значений сродни возвращению одного экземпляра анонимного класса с несколькими переменными-членами.
обработка Python аргументов метода требует возможности прямого возврата нескольких значений. В C++, например, аргументы метода могут передаваться по ссылке, поэтому вы можете назначить им выходные значения, в добавление к формальному возвращаемому значению. В Python аргументы передаются "по ссылке" (но в смысле Java, а не C++). Вы не можете присвоить новые значения аргументам метода и отразить их вне области действия метода. Например:
// C++ void test(int& arg) { arg = 1; } int foo = 0; test(foo); // foo is now 1!сравнить с:
# Python def test(arg): arg = 1 foo = 0 test(foo) # foo is still 0
Это определенно питон. Тот факт, что вы можете возвращать несколько значений из функции шаблонного шаблона, который у вас был бы на языке C, где вам нужно определить структуру для каждой комбинации типов, которые вы где-то возвращаете.
однако, если вы достигнете точки, где вы возвращаете что-то сумасшедшее, как 10 значений из одной функции, вы должны серьезно рассмотреть возможность объединения их в класс, потому что в этот момент он становится громоздким.
возвращение кортежа-это круто. Также обратите внимание на новый namedtuple который был добавлен в python 2.6, который может сделать это более приемлемым для вас: http://docs.python.org/dev/library/collections.html#collections.namedtuple
Я довольно новыми для Python, но техника кортежа, кажется, очень подходящие для Python для меня. Однако у меня была другая идея, которая может улучшить читаемость. Использование словаря позволяет получить доступ к различным значениям по имени, а не по позиции. Например:
def divide(x, y): return {'quotient': x/y, 'remainder':x%y } answer = divide(22, 7) print answer['quotient'] print answer['remainder']
OT: Algol68 RSRE имеет любопытный оператор"/:=". например.
INT quotient:=355, remainder; remainder := (quotient /:= 113);дает частное 3 и остаток 16.
Примечание: обычно значение "(x/:=y) "отбрасывается как частное" x " назначается по ссылке, но в случае RSRE возвращаемое значение является остатком.
это нормально, чтобы вернуть несколько значений с помощью кортежа для простых функций, таких как
divmod. Если это делает код читаемым, это питон.Если возвращаемое значение начинает сбивать с толку, проверьте, не делает ли функция слишком много, и разделите его, если это так. Если большой кортеж используется как объект, сделайте его объектом. Кроме того, рассмотрите возможность использования именованных кортежей, который станет частью стандартной библиотеки в Python 2.6.
Comments