Что означает оператор Star?

Возможный дубликат:
Что означает * args и ** kwargs?

Что означает оператор * в Python, например, в коде типа zip(*x) или f(**k) ?

  1. Как это делается внутри интерпретатора?
  2. Это влияет на производительность вообще? Быстро или медленно?
  3. Когда это полезно, а когда нет?
  4. Должен ли он использоваться в объявлении функции или в вызове?

5 Solutions collect form web for “Что означает оператор Star?”

Единственная звезда * распаковывает последовательность / коллекцию в позиционные аргументы, поэтому вы можете сделать это:

 def sum(a, b): return a + b values = (1, 2) s = sum(*values) 

Это распакует кортеж так, чтобы он выполнялся как:

 s = sum(1, 2) 

Двойная звезда ** делает то же самое, только используя словарь и так называемые аргументы:

 values = { 'a': 1, 'b': 2 } s = sum(**values) 

Вы также можете комбинировать:

 def sum(a, b, c, d): return a + b + c + d values1 = (1, 2) values2 = { 'c': 10, 'd': 15 } s = sum(*values1, **values2) 

будет выполняться как:

 s = sum(1, 2, c=10, d=15) 

См. Также раздел 4.7.4 – Распаковка списков аргументов документации Python.


Кроме того, вы можете определить функции для принятия аргументов *x и **y , что позволяет функции принимать любое количество позиционных и / или именованных аргументов, которые специально не указаны в объявлении.

Пример:

 def sum(*values): s = 0 for v in values: s = s + v return s s = sum(1, 2, 3, 4, 5) 

или с ** :

 def get_a(**values): return values['a'] s = get_a(a=1, b=2) # returns 1 

это может позволить вам указать большое количество необязательных параметров без их объявления.

И снова вы можете комбинировать:

 def sum(*values, **options): s = 0 for i in values: s = s + i if "neg" in options: if options["neg"]: s = -s return s s = sum(1, 2, 3, 4, 5) # returns 15 s = sum(1, 2, 3, 4, 5, neg=True) # returns -15 s = sum(1, 2, 3, 4, 5, neg=False) # returns 15 

Одна небольшая точка: это не операторы. Операторы используются в выражениях для создания новых значений из существующих значений (например, 1 + 2 становится 3. Например, * и ** являются частью синтаксиса деклараций и вызовов функций.

Он называется синтаксисом расширенного вызова. Из документации :

Если выражение синтаксиса * появляется в вызове функции, выражение должно оцениваться в последовательности. Элементы из этой последовательности обрабатываются так, как если бы они были дополнительными позиционными аргументами; если есть позиционные аргументы x1, …, xN и выражение оценивается в последовательности y1, …, yM, это эквивалентно вызову с M + N позиционными аргументами x1, …, xN, y1,. .., yM.

а также:

Если выражение функции синтаксиса ** появляется в вызове функции, выражение должно оцениваться с помощью сопоставления, содержимое которого рассматривается как дополнительные аргументы ключевого слова. В случае появления ключевого слова в обоих выражениях и в качестве явного аргумента ключевого слова возникает исключение TypeError.

Я считаю это особенно полезным, когда вы хотите «сохранить» вызов функции.

Например, предположим, что у меня есть некоторые модульные тесты для функции 'add':

 def add(a, b): return a + b tests = { (1,4):5, (0, 0):0, (-1, 3):3 } for test, result in tests.items(): print 'test: adding', test, '==', result, '---', add(*test) == result 

Нет другого способа вызвать add, кроме как вручную делать что-то вроде add (test [0], test [1]), что является уродливым. Кроме того, если есть переменное количество переменных, код может стать довольно уродливым со всеми if-утверждениями, которые вам понадобятся.

Другое место это полезно для определения объектов Factory (объектов, которые создают для вас объекты). Предположим, у вас есть класс Factory, который делает объекты Car и возвращает их. Вы можете сделать так, чтобы myFactory.make_car ('red', 'bmw', '335ix') создавал Car ('red', 'bmw', '335ix'), а затем возвращает его.

 def make_car(*args): return Car(*args) 

Это также полезно, если вы хотите вызвать конструктор суперкласса.

В вызове функции одиночная звезда превращает список в отдельные аргументы (например, zip(*x) совпадает с zip(x1,x2,x3) если x=[x1,x2,x3] ), а двойная звезда превращает словарь в отдельные аргументы ключевого слова (например, f(**k) совпадает с f(x=my_x, y=my_y) если k = {'x':my_x, 'y':my_y} .

В определении функции это наоборот: одиночная звезда превращает произвольное количество аргументов в список, а двойной старт превращает произвольное количество аргументов ключевого слова в словарь. Например, def foo(*x) означает, что «foo принимает произвольное количество аргументов, и они будут доступны через список x (т. Е. Если пользователь вызывает foo(1,2,3) , x будет [1,2,3] ) "и def bar(**k) означает, что" bar принимает произвольное количество аргументов ключевого слова, и они будут доступны через словарь k (т.е. если пользователь называет bar(x=42, y=23) , k будет {'x': 42, 'y': 23} ) ".

 
Interesting Posts for Van-Lav

Что делает оператор «есть» в Python?

Как удалить пробелы из строки в Python?

Каков правильный подход для вызова функций после запуска флеш-приложения?

Дикт слияния в понимании диктата

Ptyon ctypes – функция dll, принимающая структуры сбоев

суперпользовательские методы python

Найти все элементы с максимальным значением, производимым итератором

В Python, почему функция может изменять некоторые аргументы, воспринимаемые вызывающим, но не другие?

Первый алгоритм поиска глубины в python

Установка Python3.4.3: 3 теста не удалось, 3 изменена среда исполнения и 25 пропущенных

Найти строку в скелете Изображения OpenCV python

Как напечатать форматированную строку в Python3?

Существует ли R-эквивалент пифонического «if __name__ ==» __main__ »: main ()??

Как объявить глобальную переменную из класса?

Поддержка Chrome 59 для базовых учетных данных в URL-адресах, альтернативных для использования с Chromedriver?

Python - лучший язык программирования в мире.