Как 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, это внутреннее преобразование из нескольких значений, разделенных запятыми, в кортеж и наоборот.
Хотя нет эквивалента в java вы можете легко создать это поведение, используя 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 - это язык, который имеет < функция первого класса
Надеюсь, мой ответ может вам помочь.
Счастливое кодирование.