Чи існує спосіб передачі додаткових параметрів функції?


133

Чи є спосіб у Python передавати необов'язкові параметри функції під час виклику її, а у визначенні функції мати якийсь код, який базується на "лише у разі передачі необов'язкового параметра"

Відповіді:


115

Документація Python 2, 7.6. Визначення функції дає вам декілька способів виявити, чи викликав абонент додатковий параметр.

По-перше, ви можете використовувати спеціальний синтаксис формального параметра *. Якщо у визначенні функції є формальний параметр, якому передує одинарний *, то Python заповнює цей параметр будь-якими позиційними параметрами, які не узгоджуються з попередніми формальними параметрами (як кортеж). Якщо визначенню функції є формальний параметр, якому передує **, то Python заповнює цей параметр будь-якими параметрами ключового слова, які не узгоджуються з попередніми формальними параметрами (як дікта). Реалізація функції може перевірити вміст цих параметрів на наявність будь-яких "необов'язкових параметрів" потрібного типу.

Наприклад, ось функція , opt_funяка приймає два позиційних параметрів x1і x2, і шукають інший ключове слово параметр з ім'ям «необов'язково».

>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
...     if ('optional' in keyword_parameters):
...         print 'optional parameter found, it is ', keyword_parameters['optional']
...     else:
...         print 'no optional parameter, sorry'
... 
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is  yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry

По-друге, ви можете надати значення параметра за замовчуванням деякого значення, наприклад, Noneяке абонент ніколи не використовуватиме. Якщо параметр має це значення за замовчуванням, ви знаєте, що абонент не вказав параметр. Якщо параметр має значення за замовчуванням, ви знаєте, що він прийшов від абонента.


7
positional_parametersє кортеж і keyword_parametersсловник.
Cees Timmerman

Як пітон відрізняє formal parameters preceded by * (як це називається?) Від а keyword parameter? Як я зрозумів, параметри ключових слів задаються за допомогою =оператора у виклику функції (тому opt_fun(1,2, optional="yes")надається аргумент ключового слова "так" для функції, яка передбачає, але не обов'язково вимагає цього параметра option).
Мінь Тран

З іншого боку, я розумів formal parameters preceded by * просто "аргументи, що надаються абонентом, що не відповідають позиційним аргументам, що передує будь-яким аргументам ключових слів". Так , наприклад, в opt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018"), "blah"і 3.14це forma arguments preceded by *тому , що між двома позиційними аргументами і аргументом , який використовує =знак. Отриманий кортеж positional_parameterбуде двотактний: ("blah", 3.14). Це правильно?
Мінь Тран

@MinhTran, запитання в коментарях - не найкращий спосіб отримати відповідь у "Переповнення стека". Набагато краще натиснути на велику синю кнопку "Задати питання" і написати свій запит як "Запитання", на яке інші можуть відповісти. Але щоб вам допомогти, а) зауважте, що я написав " parameter" не " parameters" для " preceded by *". Мова містить лише один *identifierу списку параметрів. б) читати docs.python.org/2/reference/… , в) читати docs.python.org/2/reference/expressions.html#calls . На жаль, у цьому коментарі не вистачає символів.
Jim DeLaHunt

81
def my_func(mandatory_arg, optional_arg=100):
    print(mandatory_arg, optional_arg)

http://docs.python.org/2/tutorial/controlflow.html#default-argument-values

Я вважаю це більш читаним, ніж використання **kwargs.

Щоб визначити, чи взагалі передано аргумент, я використовую власний об’єкт утиліти як значення за замовчуванням:

MISSING = object()

def func(arg=MISSING):
    if arg is MISSING:
        ...

-Дякую, чи існує спосіб вказати значення за замовчуванням цього параметра як іншу змінну в коді?
користувач1795998

так. default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
Варварюк

Це відображається, щоб показати, як використовувати необов'язкові параметри, але не як перевірити, чи передано параметр, про що запитує ОП.
Мауг каже, що поверніть Моніку

4
У більшості випадків це більш просте і просте рішення, ніж рішення Джима. Якщо встановити значення за замовчуванням значення None, то ви можете перевірити, чи був параметр переданий чи ні. Єдиний випадок, коли рішення Джима краще, якщо це важливо розрізняти передачу None як аргумент і взагалі не передачу аргументу.
Арнон Аксельрод

19
def op(a=4,b=6):
    add = a+b
    print add

i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
 If none or one parameter is passed the default passed parameter will be considered for the function. 

1
Чи є спосіб передавати лише другий параметр (b), а не перший (a)?
Djidiouf

4
@Djidiouf Так, єop(b=2)
Юрґ Мерлін Спаак

7

Якщо ви хочете надати деяке значення за замовчуванням для значення присвоєння параметра в (). як (x = 10). Але перш за все важливим є обов'язковий аргумент, а потім значення за замовчуванням.

напр.

(у, х = 10)

але

(x = 10, y) неправильно


Дякую, чи є спосіб вказати значення за замовчуванням цього параметра як іншу змінну в коді?
користувач1795998

Так, ви можете використовувати щось, що називається *arg **kargаргументом функції. пошук в Google.
підсумок

Це відображається, щоб показати, як використовувати необов'язкові параметри, але не як перевірити, чи передано параметр, про що запитує ОП.
Мауг каже, що поверніть Моніку

2

Ви можете вказати значення за замовчуванням для необов'язкового аргументу з тим, що ніколи не переходило б у функцію, і перевірити це у isоператора:

class _NO_DEFAULT:
    def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()

def func(optional= _NO_DEFAULT):
    if optional is _NO_DEFAULT:
        print("the optional argument was not passed")
    else:
        print("the optional argument was:",optional)

тоді, поки ви цього не зробите, func(_NO_DEFAULT)ви зможете точно визначити, переданий аргумент чи ні, і на відміну від прийнятої відповіді, вам не доведеться турбуватися про побічні ефекти ** нотації:

# these two work the same as using **
func()
func(optional=1)

# the optional argument can be positional or keyword unlike using **
func(1) 

#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)

Просто роби _NO_DEFAULT = object().
Аран-Фей

2 додаткових рядки для кращого самоаналізу того варті. За допомогою цього, якщо ви запускаєте, help(func)ви отримуєте чіткіше уявлення про те, як аргументується інтерпретація, якщо не передається явно.
Тадг Макдональд-Дженсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.