Как Python возвращает несколько значений из функции?

Я написал следующий код:

class FigureOut:
   def setName(self, name):
      fullname = name.split()
      self.first_name = fullname[0]
      self.last_name = fullname[1]

   def getName(self):
      return self.first_name, self.last_name

f = FigureOut()
f.setName("Allen Solly")
name = f.getName()
print (name)

Я получаю следующий вывод:

('Allen', 'Solly')

Когда возвращается несколько значений из функции в python, всегда ли она преобразует несколько значений в список из нескольких значений, а затем возвращает его из функции?

Является ли весь процесс таким же, как явное преобразование нескольких значений в list, а затем возвращает список, например, в JAVA, поскольку можно вернуть только один объект из функции в JAVA?

Ответ 1

Так как оператор return в getName указывает несколько элементов:

def getName(self):
   return self.first_name, self.last_name

Python вернет контейнерный объект, который в основном содержит их.

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

Позвольте использовать более простую функцию, которая возвращает несколько значений:

def foo(a, b):
    return a, b

Вы можете посмотреть байт-код, сгенерированный с помощью dis.dis, дизассемблер для байт-кода Python. Для значений, разделенных запятыми, без каких-либо скобок, это выглядит так:

>>> import dis
>>> def foo(a, b):
...     return a,b        
>>> dis.dis(foo)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 BUILD_TUPLE              2
              9 RETURN_VALUE

Как вы можете видеть, значения сначала загружаются во внутренний стек с помощью LOAD_FAST, а затем BUILD_TUPLE (захват предыдущего 2 элементов, помещенных в стек). Python знает, как создать кортеж из-за присутствия запятых.

В качестве альтернативы вы можете указать другой тип возврата, например список, используя []. Для этого случая BUILD_LIST будет выпущен по той же семантике, что и эквивалент кортежа:

>>> def foo_list(a, b):
...     return [a, b]
>>> dis.dis(foo_list)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 BUILD_LIST               2
              9 RETURN_VALUE

Тип возвращаемого объекта действительно зависит от наличия скобок (для кортежей () можно опустить, если имеется хотя бы одна запятая). () создает кортежи, [] списки, {} устанавливает.

Подводя итог, возвращается один фактический объект. Если этот объект имеет тип контейнера, он может содержать несколько значений, давая впечатление о возврате нескольких результатов. Обычный способ состоит в том, чтобы распаковать их непосредственно:

>>> first_name, last_name = f.getName()
>>> print (first_name, last_name)

Как в стороне от всего этого, ваши пути Java проникают в Python:-)

Не используйте геттеры при написании классов в Python, используйте properties. Свойства - это идиоматический способ управления атрибутами, для получения дополнительной информации см. Хороший ответ здесь.

Ответ 2

Из Python Cookbook v.30

def myfun():
    return 1, 2, 3

a, b, c = myfun()

Хотя похоже, что myfun() возвращает несколько значений, фактически создается tuple.. Это выглядит немного странно, но на самом деле это запятая, которая образует кортеж, а не круглые скобки

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

Хотя нет эквивалента в вы можете легко создать это поведение, используя array или некоторые Collection как List s:

private static int[] sumAndRest(int x, int y) {
    int[] toReturn = new int[2];

    toReturn[0] = x + y;
    toReturn[1] = x - y;

    return toReturn;

}

Выполнено следующим образом:

public static void main(String[] args) {
    int[] results = sumAndRest(10, 5);

    int sum  = results[0];
    int rest = results[1];

    System.out.println("sum = " + sum + "\nrest = " + rest);

}

результат:

sum = 15
rest = 5

Ответ 3

Здесь он возвращает tuple.

Если вы выполните этот код в Python 3:

def get():
    a = 3
    b = 5
    return a,b
number = get()
print(type(number))
print(number)

Выход:

<class 'tuple'>
(3, 5)

Но если вы измените строку кода return [a,b] вместо return a,b и выполните:

def get():
    a = 3
    b = 5
    return [a,b]
number = get()
print(type(number))
print(number)

Выход:

<class 'list'>
[3, 5]

Он возвращает только один объект, который содержит несколько значений.

Существует другая альтернатива оператору return для возврата нескольких значений, используйте yield (подробнее см. в этом Что делает ключевое слово "yield "" в Python?)

Пример примера:

def get():
    for i in range(5):
        yield i
number = get()
print(type(number))
print(number)
for i in number:
    print(i)

Выход:

<class 'generator'>
<generator object get at 0x7fbe5a1698b8>
0
1
2
3
4

Ответ 4

Функции Python всегда возвращают уникальное значение. Оператор запятой является конструктором кортежей, поэтому self.first_name, self.last_name оценивает кортеж, а кортеж - это фактическое значение, возвращаемое функцией.

Ответ 5

Всякий раз, когда несколько значений возвращаются из функции в python, всегда ли она преобразует несколько значений в список из нескольких значений и затем возвращает их из функции?

Я просто добавляю имя и печатаю результат, возвращающийся из функции. тип результата - кортеж.

  class FigureOut:
   first_name = None
   last_name = None
   def setName(self, name):
      fullname = name.split()
      self.first_name = fullname[0]
      self.last_name = fullname[1]
      self.special_name = fullname[2]
   def getName(self):
      return self.first_name, self.last_name, self.special_name

f = FigureOut()
f.setName("Allen Solly Jun")
name = f.getName()
print type(name)


Я не знаю, слышали ли вы о функции первого класса. Python - это язык, который имеет < функция первого класса

Надеюсь, мой ответ может вам помочь. Счастливое кодирование.