Python function with keyword arguments

PEP 3102 – Keyword-Only Arguments

This PEP proposes a change to the way that function arguments are assigned to named parameter slots. In particular, it enables the declaration of “keyword-only” arguments: arguments that can only be supplied by keyword and which will never be automatically filled in by a positional argument.

Rationale

The current Python function-calling paradigm allows arguments to be specified either by position or by keyword. An argument can be filled in either explicitly by name, or implicitly by position.

There are often cases where it is desirable for a function to take a variable number of arguments. The Python language supports this using the ‘varargs’ syntax ( *name ), which specifies that any ‘left over’ arguments be passed into the varargs parameter as a tuple.

One limitation on this is that currently, all of the regular argument slots must be filled before the vararg slot can be.

This is not always desirable. One can easily envision a function which takes a variable number of arguments, but also takes one or more ‘options’ in the form of keyword arguments. Currently, the only way to do this is to define both a varargs argument, and a ‘keywords’ argument ( **kwargs ), and then manually extract the desired keywords from the dictionary.

Specification

Syntactically, the proposed changes are fairly simple. The first change is to allow regular arguments to appear after a varargs argument:

def sortwords(*wordlist, case_sensitive=False): . 

This function accepts any number of positional arguments, and it also accepts a keyword option called ‘case_sensitive’. This option will never be filled in by a positional argument, but must be explicitly specified by name.

Читайте также:  Прочитать json строку python

Keyword-only arguments are not required to have a default value. Since Python requires that all arguments be bound to a value, and since the only way to bind a value to a keyword-only argument is via keyword, such arguments are therefore ‘required keyword’ arguments. Such arguments must be supplied by the caller, and they must be supplied via keyword.

The second syntactical change is to allow the argument name to be omitted for a varargs argument. The meaning of this is to allow for keyword-only arguments for functions that would not otherwise take a varargs argument:

The reasoning behind this change is as follows. Imagine for a moment a function which takes several positional arguments, as well as a keyword argument:

Now, suppose you wanted to have ‘key’ be a keyword-only argument. Under the above syntax, you could accomplish this by adding a varargs argument immediately before the keyword argument:

def compare(a, b, *ignore, key=None): . 

Unfortunately, the ‘ignore’ argument will also suck up any erroneous positional arguments that may have been supplied by the caller. Given that we’d prefer any unwanted arguments to raise an error, we could do this:

def compare(a, b, *ignore, key=None): if ignore: # If ignore is not empty raise TypeError 

As a convenient shortcut, we can simply omit the ‘ignore’ name, meaning ‘don’t allow any positional arguments beyond this point’.

(Note: After much discussion of alternative syntax proposals, the BDFL has pronounced in favor of this ‘single star’ syntax for indicating the end of positional parameters.)

Function Calling Behavior

The previous section describes the difference between the old behavior and the new. However, it is also useful to have a description of the new behavior that stands by itself, without reference to the previous model. So this next section will attempt to provide such a description.

When a function is called, the input arguments are assigned to formal parameters as follows:

  • For each formal parameter, there is a slot which will be used to contain the value of the argument assigned to that parameter.
  • Slots which have had values assigned to them are marked as ‘filled’. Slots which have no value assigned to them yet are considered ‘empty’.
  • Initially, all slots are marked as empty.
  • Positional arguments are assigned first, followed by keyword arguments.
  • For each positional argument:
    • Attempt to bind the argument to the first unfilled parameter slot. If the slot is not a vararg slot, then mark the slot as ‘filled’.
    • If the next unfilled slot is a vararg slot, and it does not have a name, then it is an error.
    • Otherwise, if the next unfilled slot is a vararg slot then all remaining non-keyword arguments are placed into the vararg slot.
    • If there is a parameter with the same name as the keyword, then the argument value is assigned to that parameter slot. However, if the parameter slot is already filled, then that is an error.
    • Otherwise, if there is a ‘keyword dictionary’ argument, the argument is added to the dictionary using the keyword name as the dictionary key, unless there is already an entry with that key, in which case it is an error.
    • Otherwise, if there is no keyword dictionary, and no matching named parameter, then it is an error.
    • If the vararg slot is not yet filled, assign an empty tuple as its value.
    • For each remaining empty slot: if there is a default value for that slot, then fill the slot with the default value. If there is no default value, then it is an error.

    In accordance with the current Python implementation, any errors encountered will be signaled by raising TypeError . (If you want something different, that’s a subject for a different PEP.)

    Backwards Compatibility

    The function calling behavior specified in this PEP is a superset of the existing behavior — that is, it is expected that any existing programs will continue to work.

    This document has been placed in the public domain.

    Источник

    Python Keyword Arguments

    You can also send arguments with the key = value syntax.

    This way the order of the arguments does not matter.

    Example

    def my_function(child3, child2, child1):
    print(«The youngest child is » + child3)

    my_function(child1 = «Emil», child2 = «Tobias», child3 = «Linus»)

    The phrase Keyword Arguments are often shortened to kwargs in Python documentations.

    Unlock Full Access 50% off

    COLOR PICKER

    colorpicker

    Join our Bootcamp!

    Report Error

    If you want to report an error, or if you want to make a suggestion, do not hesitate to send us an e-mail:

    Thank You For Helping Us!

    Your message has been sent to W3Schools.

    Top Tutorials
    Top References
    Top Examples
    Get Certified

    W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

    Источник

    How can I pass keyword arguments as parameters to a function?

    Inside outer_func I want to be able to call inner_func with exactly the same parameters that were passed into outer_func . This can be achieved by writing outer_func like this:

    def outer_func(spam, eggs): inner_func(spam, eggs) 

    However, I’d like to be able to change the arguments inner_func takes, and change the parameters I pass to outer_func accordingly, but without having to change anything in outer_func each time. Is there a (easy) way to do this? Python 3 please.

    I’m not sure I get what you’re trying to do. It seems like you want func_one to call func_two , and that sometimes you want the same parameters and sometimes you want different ones. Which is vague. Can you provide an example of the functionality you want?

    When you say «without changing the definition of outer_func «, do you mean without changing it every time you change inner_func , or do you mean the definition should still say def outer_func(spam, eggs): exactly the way it does now when you’re done?

    2 Answers 2

    Looks like you’re looking for the * and ** notations:

    def outer_func(*args, **kwargs): inner_func(*args, **kwargs) 

    Then you can do outer_func(1, 2, 3, a=’x’, b=’y’) , and outer_func will call inner_func(1, 2, 3, a=’x’, b=’y’) .

    If you only want to allow keyword arguments, drop the *args .

    In a function definition, a parameter marked with * receives a tuple of all positional arguments that didn’t correspond to other declared parameters, and an argument marked with ** receives a dict of all keyword arguments that didn’t correspond to other declared parameters.

    In a function call, prefixing a sequence (or other iterable) argument with * unpacks it into separate positional arguments, and prefixing a mapping argument with ** unpacks it into separate keyword arguments.

    @wim: I’m pretty sure that’s intended to mean «without changing the definition of outer_func every time I change inner_func «, but I could be wrong.

    Thank you! This is exactly what I was looking for. I knew about using the * as an argument, but I didn’t know you could use it to unpack a tuple or dict when passing function parameters.

    Not entirely sure I’m getting your drift but you may find functools.wraps interesting:

    @functools.wraps(inner_func) def outer_func(*args, **kwds): return inner_func(*args, **kwds) inspect.signature(outer_func) #

    Explanation: The «star arguments» collect all the not explicitly specified postional (*args) and keyword (**kwds) arguments that were passed. They can also be used to pass these parameters on; or to manipulate them: args is a tuple and kwds is a dict.

    Since for example parameter spam will end up either in args or kwds depending on how it was passed, manually parsing star args can be tedious. Here the inspect.Signature class and in particular its .bind and .bind_partial methods are useful.

    functools.wraps is a convenience function/decorator that tweaks many special attributes of the decorated function to make it look like the wrapped function. In particular it copies the name, the signature, the doc string and whatever may be in the wrapped functions __dict__ .

    This makes wrapper functions much more user friendly.

    Источник

Оцените статью