Zoeken…


Opmerkingen

Er zijn een paar dingen om op te merken:

  1. De namen args en kwargs worden volgens afspraak gebruikt, ze maken geen deel uit van de taalspecificatie. Deze zijn dus equivalent:

     def func(*args, **kwargs):
         print(args)
         print(kwargs)
    

     def func(*a, **b):
         print(a)
         print(b)
    
  2. U mag niet meer dan één args of meer dan één kwargs parameters hebben (deze zijn echter niet vereist)

     def func(*args1, *args2):
     #   File "<stdin>", line 1
     #     def test(*args1, *args2):
     #                      ^
     # SyntaxError: invalid syntax
    

     def test(**kwargs1, **kwargs2):
     #   File "<stdin>", line 1
     #     def test(**kwargs1, **kwargs2):
     #                       ^
     # SyntaxError: invalid syntax
    
  3. Als er een positioneel argument *args , zijn dit alleen sleutelwoorden die alleen op naam kunnen worden doorgegeven. Een enkele ster kan worden gebruikt in plaats van *args om waarden te dwingen zoekwoordargumenten te zijn zonder een variadische parameterlijst te bieden. Parameterlijsten met alleen zoekwoorden zijn alleen beschikbaar in Python 3.

     def func(a, b, *args, x, y):
         print(a, b, args, x, y)
    
     func(1, 2, 3, 4, x=5, y=6)
     #>>> 1, 2, (3, 4), 5, 6
    

     def func(a, b, *, x, y):
         print(a, b, x, y)
    
     func(1, 2, x=5, y=6)
     #>>> 1, 2, 5, 6
    
  4. **kwargs moet als laatste in de parameterlijst komen.

     def test(**kwargs, *args):
     #   File "<stdin>", line 1
     #     def test(**kwargs, *args):
     #                      ^
     # SyntaxError: invalid syntax
    

* Args gebruiken bij het schrijven van functies

U kunt de ster * gebruiken bij het schrijven van een functie om alle positionele (dat wil zeggen niet-genoemde) argumenten in een tuple te verzamelen:

def print_args(farg, *args):
   print("formal arg: %s" % farg)
   for arg in args:
       print("another positional arg: %s" % arg)

Bellen methode:

print_args(1, "two", 3)

In die call zal farg worden toegewezen zoals altijd, en de twee anderen zullen in het args-tuple worden ingevoerd, in de volgorde waarin ze zijn ontvangen.

** kwargs gebruiken bij het schrijven van functies

U kunt een functie definiëren waarvoor een willekeurig aantal trefwoord (benoemde) argumenten nodig is door de dubbele ster ** voor een parameternaam te gebruiken:

def print_kwargs(**kwargs):
    print(kwargs)

Wanneer de methode wordt aangeroepen, maakt Python een woordenboek met alle trefwoordargumenten en maakt deze beschikbaar in de hoofdtekst:

print_kwargs(a="two", b=3)
# prints: "{a: "two", b=3}"

Merk op dat de parameter ** kwargs in de functiedefinitie altijd de laatste parameter moet zijn en alleen overeenkomt met de argumenten die zijn doorgegeven na de vorige.

def example(a, **kw):
    print kw

example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}

Binnen de functie wordt kwargs op dezelfde manier gemanipuleerd als een woordenboek; om toegang te krijgen tot individuele elementen in kwargs loop je ze gewoon door zoals je zou doen met een normaal woordenboek:

def print_kwargs(**kwargs):
    for key in kwargs:
        print("key = {0}, value = {1}".format(key, kwargs[key])) 

Als u nu print_kwargs(a="two", b=1) wordt de volgende uitvoer weergegeven:

print_kwargs(a = "two", b = 1)
key = a, value = "two"
key = b, value = 1

* Args gebruiken bij het aanroepen van functies

Een veelvoorkomende use case voor *args in een functiedefinitie is om de verwerking te delegeren aan een verpakte of geërfde functie. Een typisch voorbeeld kan de __init__ methode van een klasse zijn

class A(object):
    def __init__(self, b, c):
        self.y = b
        self.z = c

class B(A):
    def __init__(self, a, *args, **kwargs):
        super(B, self).__init__(*args, **kwargs)
        self.x = a

Hier wordt de parameter a verwerkt door de onderliggende klasse nadat alle andere argumenten (positioneel en trefwoord) zijn doorgegeven aan - en verwerkt door - de basisklasse.

Bijvoorbeeld:

b = B(1, 2, 3)
b.x  # 1
b.y  # 2
b.z  # 3

Wat hier gebeurt, is dat de klasse B __init__ functie de argumenten 1, 2, 3 . Het weet dat het één positioneel argument ( a ) moet aannemen, dus het grijpt het eerste argument door dat in ( 1 ) is doorgegeven, dus in het bereik van de functie a == 1 .

Vervolgens ziet het dat het een willekeurig aantal positionele argumenten ( *args ) moet nemen, dus het neemt de rest van de doorgegeven positieargumenten ( 1, 2 ) en stopt ze in *args . Nu (in het kader van de functie) args == [2, 3] .

Vervolgens wordt de functie __init__ klasse A met *args __init__ . Python ziet de * voor args en "pakt de lijst uit" in argumenten. Wanneer in dit voorbeeld de functie __init__ klasse B de functie __init__ klasse A __init__ , worden de argumenten 2, 3 (dwz A(2, 3) ) doorgegeven.

Ten slotte stelt het zijn eigen eigenschap x in op het eerste positionele argument a , dat gelijk is aan 1 .

** kwargs gebruiken bij het aanroepen van functies

U kunt een woordenboek gebruiken om waarden toe te wijzen aan de parameters van de functie; met behulp van parameternaam als sleutels in het woordenboek en de waarde van deze argumenten gebonden aan elke sleutel:

def test_func(arg1, arg2, arg3): # Usual function with three arguments
   print("arg1: %s" % arg1)
   print("arg2: %s" % arg2)
   print("arg3: %s" % arg3)

# Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter.
kwargs = {"arg3": 3, "arg2": "two"}

# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others
test_var_args_call(1, **kwargs) 

* Args gebruiken bij het aanroepen van functies

Het effect van het gebruik van de operator * op een argument bij het aanroepen van een functie is dat de lijst of een tuple-argument wordt uitgepakt

def print_args(arg1, arg2):
    print(str(arg1) + str(arg2))

a = [1,2]
b = tuple([3,4])

print_args(*a)
# 12
print_args(*b)
# 34

Merk op dat de lengte van het argument met ster gelijk moet zijn aan het aantal argumenten van de functie.

Een gebruikelijk python-idioom is om de uitpakkingsoperator * met de zip functie te gebruiken om de effecten om te keren:

a = [1,3,5,7,9]
b = [2,4,6,8,10]

zipped = zip(a,b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]

zip(*zipped)
# (1,3,5,7,9), (2,4,6,8,10)

Alleen-trefwoord en trefwoord-vereiste argumenten

Met Python 3 kunt u functieargumenten definiëren die alleen per trefwoord kunnen worden toegewezen, zelfs zonder standaardwaarden. Dit wordt gedaan door star * te gebruiken om extra positionele parameters te gebruiken zonder de trefwoordparameters in te stellen. Alle argumenten na de * zijn alleen-trefwoord (dwz niet-positionele) argumenten. Houd er rekening mee dat als alleen zoekwoordargumenten geen standaardwaarde krijgen, ze nog steeds vereist zijn bij het aanroepen van de functie.

def print_args(arg1, *args, keyword_required, keyword_only=True):
    print("first positional arg: {}".format(arg1))
    for arg in args:
        print("another positional arg: {}".format(arg))
    print("keyword_required value: {}".format(keyword_required))
    print("keyword_only value: {}".format(keyword_only))
    
print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 'keyword_required'
print(1, 2, 3, keyword_required=4) 
# first positional arg: 1
# another positional arg: 2
# another positional arg: 3
# keyword_required value: 4
# keyword_only value: True

Kwarg-waarden vullen met een woordenboek

def foobar(foo=None, bar=None):
    return "{}{}".format(foo, bar)

values = {"foo": "foo", "bar": "bar"}

foobar(**values) # "foobar"

** kwargs en standaardwaarden

Standaardwaarden gebruiken met ** kwargs

def fun(**kwargs):
    print kwargs.get('value', 0)

fun()
# print 0
fun(value=1)
# print 1


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow