Sök…


Introduktion

Funktioner i Python ger organiserad, återanvändbar och modulär kod för att utföra en uppsättning specifika åtgärder. Funktioner förenklar kodningsprocessen, förhindrar redundant logik och gör koden lättare att följa. Detta ämne beskriver deklarationen och användningen av funktioner i Python.

Python har många inbyggda funktioner som print() , input() , len() . Förutom inbyggda kan du också skapa dina egna funktioner för att göra mer specifika jobb - dessa kallas användardefinierade funktioner .

Syntax

  • def function_name ( arg1, ... argN, * args, kw1, kw2 = default, ..., ** kwargs ): uttalanden
  • lambda arg1, ... argN, * args, kw1, kw2 = standard, ..., ** kwargs : expression

parametrar

Parameter detaljer
arg1 , ..., argN Vanliga argument
* args Namnlösa positionella argument
kw1 , ..., kwN Argument med nyckelord
** kwargs Resten av sökordsargument

Anmärkningar

5 grundläggande saker du kan göra med funktioner:

  • Tilldela funktioner till variabler

    def f():
      print(20)
    y = f
    y()
    # Output: 20
    
  • Definiera funktioner inom andra funktioner ( Nested-funktioner )

    def f(a, b, y):
        def inner_add(a, b):      # inner_add is hidden from outer code
            return a + b
        return inner_add(a, b)**y
    
  • Funktioner kan returnera andra funktioner

    def f(y):
        def nth_power(x):
            return x ** y
        return nth_power    # returns a function
    
    squareOf = f(2)         # function that returns the square of a number           
    cubeOf = f(3)           # function that returns the cube of a number
    squareOf(3)             # Output: 9
    cubeOf(2)               # Output: 8
    
  • Funktioner kan skickas som parametrar till andra funktioner

    def a(x, y):
        print(x, y)
    def b(fun, str):        # b has two arguments: a function and a string 
        fun('Hello', str)
    b(a, 'Sophia')           # Output: Hello Sophia
    
  • Inre funktioner har åtkomst till det slutande omfånget ( Stängning )

    def outer_fun(name):
        def inner_fun():     # the variable name is available to the inner function
            return "Hello "+ name + "!"
        return inner_fun
    greet = outer_fun("Sophia")
    print(greet())            # Output: Hello Sophia!
    

Ytterligare resurser

Definiera och ringa enkla funktioner

Att använda def uttalandet är det vanligaste sättet att definiera en funktion i python. Detta uttalande är ett så kallad sammansatt uttalande med en enda klausul med följande syntax:

def function_name(parameters):
    statement(s)

function_name kallas function_name identifierare . Eftersom en funktionsdefinition är ett körbart uttalande binder dess körning funktionsnamnet till funktionsobjektet som kan kallas senare med hjälp av identifieraren.

parameters är en valfri lista med identifierare som blir bundna till värdena som levereras som argument när funktionen anropas. En funktion kan ha ett godtyckligt antal argument som är separerade med kommatecken.

statement(s) - även känd som funktionsorganet - är en sekvens av uttalanden som utförs varje gång funktionen anropas. Detta betyder att en funktionskropp inte kan vara tom, precis som något intryckt block .

Här är ett exempel på en enkel funktionsdefinition vilket syfte är att skriva ut Hello varje gång det heter:

def greet():
    print("Hello")

Låt oss nu kalla den definierade greet() -funktionen:

greet()
# Out: Hello

Det är ett annat exempel på en funktionsdefinition som tar ett enda argument och visar det godkända värdet varje gång funktionen kallas:

def greet_two(greeting):
    print(greeting)

Därefter greet_two() -funktionen kallas med ett argument:

greet_two("Howdy")
# Out: Howdy

Du kan också ge ett standardvärde för det funktionsargumentet:

def greet_two(greeting="Howdy"):
    print(greeting)

Nu kan du ringa funktionen utan att ge ett värde:

greet_two()
# Out: Howdy 

Du kommer att märka att till skillnad från många andra språk behöver du inte uttryckligen förklara en återgångstyp för funktionen. Python funktioner kan returnera värden av något slag via return sökord. En funktion kan returnera valfritt antal olika typer!

def many_types(x):
    if x < 0:
        return "Hello!"
    else:
        return 0

print(many_types(1))
print(many_types(-1))

# Output:
0
Hello!

Så länge detta hanteras korrekt av den som ringer, är detta perfekt giltig Python-kod.

En funktion som når slutet av exekveringen utan ett returrätt kommer alltid att returnera None :

def do_nothing():
    pass

print(do_nothing())
# Out: None

Som tidigare nämnts måste en funktionsdefinition ha ett funktionsorgan, en sekvens med uttalanden. Därför pass uttalande används som funktions kroppen, vilket är en noll operation - när det utförs, händer ingenting. Det gör vad det betyder, det hoppar över. Det är användbart som platshållare när ett uttalande krävs syntaktiskt, men ingen kod behöver köras.

Återvända värden från funktioner

Funktioner kan return ett värde som du kan använda direkt:

def give_me_five():
    return 5

print(give_me_five())  # Print the returned value
# Out: 5

eller spara värdet för senare användning:

num = give_me_five()
print(num)             # Print the saved returned value
# Out: 5

eller använd värdet för alla operationer:

print(give_me_five() + 10)
# Out: 15

Om return stöds i funktionen kommer funktionen att avslutas omedelbart och efterföljande operationer utvärderas inte:

def give_me_another_five():
    return 5
    print('This statement will not be printed. Ever.')

print(give_me_another_five())
# Out: 5

Du kan också return flera värden (i form av en tupel):

def give_me_two_fives():
    return 5, 5  # Returns two 5

first, second = give_me_two_fives()
print(first)
# Out: 5
print(second)
# Out: 5

En funktion utan return uttalande återförstått None . På liknande sätt return en funktion med ett returrätt, men inget returvärde eller variabel returnerar None .

Definiera en funktion med argument

Argument definieras inom parentes efter funktionsnamnet:

def divide(dividend, divisor):  # The names of the function and its arguments
    # The arguments are available by name in the body of the function
    print(dividend / divisor)

Funktionsnamnet och dess lista med argument kallas funktionens signatur . Varje namngivet argument är i själva verket en lokal variabel av funktionen.

När du ringer till funktionen, ge värden för argumenten genom att lista dem i ordning

divide(10, 2)
# output: 5

eller ange dem i valfri ordning med namnen från funktionsdefinitionen:

divide(divisor=2, dividend=10)
# output: 5

Definiera en funktion med valfria argument

Valfria argument kan definieras genom att tilldela (med = ) ett standardvärde till argumentnamnet:

def make(action='nothing'):
    return action

Det är möjligt att ringa denna funktion på tre olika sätt:

make("fun")
# Out: fun

make(action="sleep")
# Out: sleep

# The argument is optional so the function will use the default value if the argument is 
# not passed in.
make()   
# Out: nothing

Varning

Bytbara typer ( list , dict , set etc.) ska behandlas med försiktighet när de ges som standardattribut . Varje mutation av standardargumentet kommer att ändra det permanent. Se Definiera en funktion med valfria, muterbara argument .

Definiera en funktion med flera argument

Man kan ge en funktion så många argument man vill, de enda fasta reglerna är att varje argumentnamn måste vara unikt och att valfria argument måste vara efter de icke-frivilliga:

def func(value1, value2, optionalvalue=10):
    return '{0} {1} {2}'.format(value1, value2, optionalvalue1)

När du ringer till funktionen kan du antingen ge varje nyckelord utan namnet men då är ordningen viktig:

print(func(1, 'a', 100))
# Out: 1 a 100

print(func('abc', 14))
# abc 14 10

Eller kombinera att ge argumenten med namn och utan. Då måste de med namn följa de utan men ordningen på de med namn spelar ingen roll:

print(func('This', optionalvalue='StackOverflow Documentation', value2='is'))
# Out: This is StackOverflow Documentation

Definiera en funktion med ett godtyckligt antal argument

Godtyckligt antal positionella argument:

Definiera en funktion som kan ta ett godtyckligt antal argument kan göras genom att prefixera ett av argumenten med ett *

def func(*args):
    # args will be a tuple containing all values that are passed in
    for i in args:
        print(i)

func(1, 2, 3)  # Calling it with 3 arguments
# Out: 1
#      2
#      3

list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values)  # Calling it with list of values, * expands the list
# Out: 1
#      2
#      3 

func()  # Calling it without arguments
# No Output 

Du kan inte ange ett standardvärde för args , till exempel func(*args=[1, 2, 3]) kommer att höja ett syntaxfel (kommer inte ens att kompilera).

Du kan inte ange dessa med namn när du ringer funktionen, till exempel func(*args=[1, 2, 3]) kommer att höja en TypeError .

Men om du redan har dina argument i en array (eller någon annan Iterable ), kan du anropa din funktion så här: func(*my_stuff) .

Dessa argument ( *args ) kan nås med index, till exempel args[0] kommer att returnera det första argumentet

Godtyckligt antal sökordsargument

Du kan ta ett godtyckligt antal argument med ett namn genom att definiera ett argument i definitionen med två * framför:

def func(**kwargs):
    # kwargs will be a dictionary containing the names as keys and the values as values
    for name, value in kwargs.items():
        print(name, value)

func(value1=1, value2=2, value3=3)   # Calling it with 3 arguments
# Out: value1 1
#      value2 2
#      value3 3

func()                               # Calling it without arguments
# No Out put

my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                      # Calling it with a dictionary
# Out: foo 1
#      bar 2

Du kan inte ange dessa utan namn, till exempel func(1, 2, 3) höjer en TypeError .

kwargs är en vanlig python-ordbok. Till exempel args['value1'] kommer att ge värde för argumentet value1 . Var noga med att kontrollera i förväg att det finns ett sådant argument eller att KeyError kommer att tas upp.

Varning

Du kan blanda dessa med andra valfria och nödvändiga argument men ordningen i definitionen är viktig.

Positionerings- / nyckelordargumenten kommer först. (Obligatoriska argument).
Sedan kommer de godtyckliga *arg argumenten. (Valfri).
Sedan kommer nästa argument med nyckelord . (Nödvändig).
Slutligen kommer det godtyckliga nyckelordet **kwargs . (Valfri).

#       |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass
  • arg1 måste anges, annars TypeError en TypeError upp. Det kan anges som position ( func(10) ) eller nyckelordargument ( func(arg1=10) ).
  • kwarg1 måste också anges, men det kan endast tillhandahållas som nyckelord-argument: func(kwarg1=10) .
  • arg2 och kwarg2 är valfria. Om värdet ska ändras gäller samma regler som för arg1 (antingen position eller nyckelord) och kwarg1 (endast nyckelord).
  • *args fångar ytterligare positionsparametrar. Men notera att arg1 och arg2 måste tillhandahållas som positionsargument för att skicka argument till *args : func(1, 1, 1, 1) .
  • **kwargs fångar alla ytterligare sökordsparametrar. I detta fall någon parameter som inte är arg1 , arg2 , kwarg1 eller kwarg2 . Till exempel: func(kwarg3=10) .
  • I Python 3 kan du använda * ensam för att indikera att alla efterföljande argument måste anges som nyckelord. Exempelvis math.isclose funktionen i Python 3.5 och högre med def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , vilket innebär att de två första argumenten kan tillhandahållas positivt men valfritt tredje och fjärde parametrarna kan endast tillhandahållas som sökordargument.

Python 2.x stöder inte parametrar för endast sökord. Detta beteende kan emuleras med kwargs :

def func(arg1, arg2=10, **kwargs):
    try:
        kwarg1 = kwargs.pop("kwarg1")
    except KeyError:
        raise TypeError("missing required keyword-only argument: 'kwarg1'")

    kwarg2 = kwargs.pop("kwarg2", 2)
    # function body ...

Obs om namngivning

Konventionen att namnge valfria positionsargument args och valfria kwargs är bara en konvention du kan använda alla namn du gillar men det är användbart att följa konventionen så att andra vet vad du gör, eller till och med dig själv senare, så gör det.

Obs om unikhet

Varje funktion kan definieras med ingen eller en *args och ingen eller en **kwargs men inte med mer än en av var och en. Även *args måste vara det sista positionsargumentet och **kwargs måste vara den sista parametern. Försök att använda mer än en av antingen kommer att resultera i ett syntaxfel undantag.

Notera om häckfunktioner med valfria argument

Det är möjligt att häcka sådana funktioner och den vanliga konventionen är att ta bort de objekt som koden redan har hanterat, men om du skickar ned parametrarna måste du passera valfritt positionsargument med ett * prefix och valfritt nyckelord args med ett ** prefix. , annars args med att ges som en lista eller tupel och kwargs som en enda ordbok. t.ex:

def fn(**kwargs):
    print(kwargs)
    f1(**kwargs)

def f1(**kwargs):
    print(len(kwargs))

fn(a=1, b=2)
# Out:
# {'a': 1, 'b': 2}
# 2

Definiera en funktion med valfria, muterbara argument

Det finns ett problem när du använder valfria argumenter med en muterbar standardtyp (beskrivs i Definiera en funktion med valfria argument ), vilket kan leda till oväntat beteende.

Förklaring

Det här problemet uppstår på grund av att en funktions standardargument initialiseras en gång , vid den punkt då funktionen definieras , och inte (som många andra språk) när funktionen anropas . Standardvärdena lagras i funktionsobjektets __defaults__ medlemsvariabel.

def f(a, b=42, c=[]):
    pass

print(f.__defaults__)
# Out: (42, [])

För oföränderliga typer (se Argumentpassering och mutabilitet ) är detta inte ett problem eftersom det inte finns något sätt att mutera variabeln; det kan bara ändras om, så att det ursprungliga värdet är oförändrat. Följaktligen garanteras efterföljande samma standardvärde. För en muterbar typ kan emellertid det ursprungliga värdet mutera genom att ringa till dess olika medlemsfunktioner. Därför garanteras inte successiva samtal till funktionen det ursprungliga standardvärdet.

def append(elem, to=[]):
    to.append(elem)      # This call to append() mutates the default variable "to"
    return to

append(1)
# Out: [1]

append(2)  # Appends it to the internally stored list
# Out: [1, 2]

append(3, [])  # Using a new created list gives the expected result
# Out: [3]

# Calling it again without argument will append to the internally stored list again
append(4)   
# Out: [1, 2, 4]

Obs: Vissa IDE: er som PyCharm kommer att ge en varning när en muterbar typ anges som standardattribut.

Lösning

Om du vill se till att standardargumentet alltid är det du anger i funktionsdefinitionen, är lösningen att alltid använda en immutable-typ som ditt standardargument.

Ett vanligt formspråk för att uppnå detta när en muterbar typ behövs som standard, är att använda None (immutable) som standardargument och sedan tilldela det faktiska standardvärdet till argumentvariabeln om det är lika med None .

def append(elem, to=None):
    if to is None:
        to = []

    to.append(elem)
    return to

Lambda (inline / anonyma) funktioner

lambda nyckelordet skapar en inline-funktion som innehåller ett enda uttryck. Värdet på detta uttryck är vad funktionen returnerar när den åberopas.

Tänk på funktionen:

def greeting():
    return "Hello"

vilket, när det kallas som:

print(greeting())

grafik:

Hello

Detta kan skrivas som en lambda-funktion på följande sätt:

greet_me = lambda: "Hello"

Se not längst ned i detta avsnitt angående tilldelning av lambdas till variabler. Generellt gör det inte.

Detta skapar en inline-funktion med namnet greet_me som returnerar Hello . Observera att du inte skriver return när du skapar en funktion med lambda. Värdet efter : returneras automatiskt.

När den har tilldelats en variabel kan den användas precis som en vanlig funktion:

print(greet_me())

grafik:

Hello

lambda s kan också ta argument:

strip_and_upper_case = lambda s: s.strip().upper()

strip_and_upper_case("  Hello   ")

returnerar strängen:

HELLO

De kan också ta godtyckligt antal argument / nyckelordargument, som vanliga funktioner.

greeting = lambda x, *args, **kwargs: print(x, args, kwargs)
greeting('hello', 'world', world='world')

grafik:

hello ('world',) {'world': 'world'}

lambda används ofta för korta funktioner som är praktiska att definiera vid den punkt där de kallas (vanligtvis med sorted , filter och map ).

Till exempel sorterar denna rad en lista med strängar som ignorerar deras fall och ignorerar vitrummet i början och i slutet:

sorted( [" foo ", "    bAR", "BaZ    "], key=lambda s: s.strip().upper())
# Out:
# ['    bAR', 'BaZ    ', ' foo ']

Sortera listan som bara ignorerar blanksteg:

sorted( [" foo ", "    bAR", "BaZ    "], key=lambda s: s.strip())
# Out:
# ['BaZ    ', '    bAR', ' foo ']

Exempel med map :

sorted( map( lambda s: s.strip().upper(), [" foo ", "    bAR", "BaZ    "]))
# Out:
# ['BAR', 'BAZ', 'FOO']

sorted( map( lambda s: s.strip(), [" foo ", "    bAR", "BaZ    "]))
# Out:
# ['BaZ', 'bAR', 'foo']

Exempel med numeriska listor:

my_list = [3, -4, -2, 5, 1, 7]
sorted( my_list, key=lambda x: abs(x))
# Out:
# [1, -2, 3, -4, 5, 7]

list( filter( lambda x: x>0, my_list))
# Out:
# [3, 5, 1, 7]

list( map( lambda x: abs(x), my_list))
# Out:
[3, 4, 2, 5, 1, 7]

Man kan ringa andra funktioner (med / utan argument) inifrån en lambda-funktion.

def foo(msg):
    print(msg)

greet = lambda x = "hello world": foo(x)
greet()

grafik:

hello world

Detta är användbart eftersom lambda kan innehålla ett uttryck och genom att använda en subsidiär funktion kan man köra flera uttalanden.


NOTERA

Tänk på att PEP-8 (den officiella Python-stilguiden) inte rekommenderar att tilldela lambdas till variabler (som vi gjorde i de två första exemplen):

Använd alltid ett def-uttalande istället för ett tilldelningsuttalande som binder ett lambda-uttryck direkt till en identifierare.

Ja:

def f(x): return 2*x

Nej:

f = lambda x: 2*x

Den första formen innebär att namnet på det resulterande funktionsobjektet specifikt är f istället för det generiska <lambda> . Detta är mer användbart för tracebacks och strängrepresentationer i allmänhet. Användningen av uppdragsbeskrivningen eliminerar den enda fördel som ett lambda-uttryck kan erbjuda över ett uttryckligt def uttalande (dvs. att det kan inbäddas i ett större uttryck).

Argumentpassering och mutabilitet

Först en del terminologi:

  • argument ( faktisk parameter): den faktiska variabeln som skickas till en funktion;
  • parameter ( formell parameter): den mottagande variabeln som används i en funktion.

I Python skickas argument efter tilldelning (i motsats till andra språk, där argument kan skickas efter värde / referens / pekare).

  • Om du stänger av en parameter kommer du att mutera argumentet (om argumentets typ är muterat).

    def foo(x):        # here x is the parameter
        x[0] = 9       # This mutates the list labelled by both x and y
        print(x)
    
    y = [4, 5, 6]
    foo(y)             # call foo with y as argument
    # Out: [9, 5, 6]   # list labelled by x has been mutated
    print(y)           
    # Out: [9, 5, 6]   # list labelled by y has been mutated too
    
  • Omfördela parametern kommer inte att tilldela argumentet.

    def foo(x):        # here x is the parameter, when we call foo(y) we assign y to x
        x[0] = 9       # This mutates the list labelled by both x and y
        x = [1, 2, 3]  # x is now labeling a different list (y is unaffected)
        x[2] = 8       # This mutates x's list, not y's list
      
    y = [4, 5, 6]      # y is the argument, x is the parameter
    foo(y)             # Pretend that we wrote "x = y", then go to line 1
    y
    # Out: [9, 5, 6]
    

I Python tilldelar vi inte riktigt värden till variabler utan vi binder (dvs. tilldelar, bifogar) variabler (betraktas som namn ) till objekt.

  • Oändligt: heltal, strängar, tuplor och så vidare. Alla åtgärder gör kopior.
  • Bärbar: Listor, ordböcker, uppsättningar och så vidare. Åtgärderna kan eventuellt mutera.
x = [3, 1, 9]
y = x
x.append(5)    # Mutates the list labelled by x and y, both x and y are bound to [3, 1, 9]
x.sort()       # Mutates the list labelled by x and y (in-place sorting)
x = x + [4]    # Does not mutate the list (makes a copy for x only, not y)
z = x          # z is x ([1, 3, 9, 4])
x += [6]       # Mutates the list labelled by both x and z (uses the extend function).
x = sorted(x)  # Does not mutate the list (makes a copy for x only).
x
# Out: [1, 3, 4, 5, 6, 9]
y
# Out: [1, 3, 5, 9]
z
# Out: [1, 3, 5, 9, 4, 6]

Stängning

Stängningar i Python skapas av funktionssamtal. Här skapar samtalet till makeInc en bindning för x som refereras inuti funktionen inc . Varje samtal till makeInc skapar en ny instans av den här funktionen, men varje instans har en länk till en annan bindning av x .

def makeInc(x):
  def inc(y):
     # x is "attached" in the definition of inc
     return y + x

  return inc

incOne = makeInc(1)
incFive = makeInc(5)

incOne(5) # returns 6
incFive(5) # returns 10

Lägg märke till att den slutna funktionen i en regelbunden nedläggning ärver alla variabler från dess omgivande miljö, men i den här konstruktionen har den slutna funktionen bara läsåtkomst till de ärvda variablerna men kan inte göra uppdrag till dem

def makeInc(x):
  def inc(y):
     # incrementing x is not allowed
     x += y  
     return x

  return inc

incOne = makeInc(1)
incOne(5) # UnboundLocalError: local variable 'x' referenced before assignment

Python 3 erbjuder det nonlocal uttalandet ( Nonlocal Variables ) för att realisera en fullständig stängning med kapslade funktioner.

Python 3.x 3.0
def makeInc(x):
  def inc(y):
     nonlocal x
     # now assigning a value to x is allowed
     x += y  
     return x

  return inc

incOne = makeInc(1)
incOne(5) # returns 6

Rekursiva funktioner

En rekursiv funktion är en funktion som kallar sig själv i sin definition. Till exempel den matematiska funktionen, factorial, definierad av factorial(n) = n*(n-1)*(n-2)*...*3*2*1 . kan programmeras som

def factorial(n):
    #n here should be an integer
    if n == 0:
        return 1
    else:
        return n*factorial(n-1)

utgångarna här är:

factorial(0)
#out 1
factorial(1)
#out 1
factorial(2)
#out 2
factorial(3)
#out 6

som förväntat. Lägg märke till att den här funktionen är rekursiv eftersom den andra return factorial(n-1) , där funktionen kallar sig själv i sin definition.

Vissa rekursiva funktioner kan implementeras med lambda , faktorfunktionen med lambda skulle vara något liknande:

factorial = lambda n: 1 if n == 0 else n*factorial(n-1)

Funktionen matar ut samma sak som ovan.

Rekursionsgräns

Det finns en gräns för djupet för möjlig rekursion, vilket beror på Python-implementeringen. När gränsen uppnås höjs ett RuntimeError-undantag:

def cursing(depth):
  try:
    cursing(depth + 1) # actually, re-cursing
  except RuntimeError as RE:
    print('I recursed {} times!'.format(depth))

cursing(0)
# Out: I recursed 1083 times!

Det är möjligt att ändra gränsen för rekursionsdjup genom att använda sys.setrecursionlimit(limit) och kontrollera denna gräns med sys.getrecursionlimit() .

sys.setrecursionlimit(2000)
cursing(0)
# Out: I recursed 1997 times!

Från Python 3.5 är undantaget en RecursionError , som härrör från RuntimeError .

Kapslade funktioner

Funktioner i python är förstklassiga objekt. De kan definieras i valfritt omfång

def fibonacci(n):
    def step(a,b):
        return b, a+b
    a, b = 0, 1
    for i in range(n):
        a, b = step(a, b)
    return a

Funktioner som fångar deras omslutande räckvidd kan skickas runt som alla andra slags objekt

def make_adder(n):
    def adder(x):
        return n + x
    return adder
add5 = make_adder(5)
add6 = make_adder(6)
add5(10)
#Out: 15
add6(10)
#Out: 16

def repeatedly_apply(func, n, x):
    for i in range(n):
        x = func(x)
    return x

repeatedly_apply(add5, 5, 1)
#Out: 26

Iterable och ordbok uppackning

Funktioner låter dig ange dessa typer av parametrar: position, namngiven, variabel position, sökordsarg (kwargs). Här är en tydlig och kortfattad användning av varje typ.

def unpacking(a, b, c=45, d=60, *args, **kwargs):
    print(a, b, c, d, args, kwargs)

>>> unpacking(1, 2)
1 2 45 60 () {}
>>> unpacking(1, 2, 3, 4)
1 2 3 4 () {}
>>> unpacking(1, 2, c=3, d=4)
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, c=3)
1 2 3 4 () {}


>>> pair = (3,)
>>> unpacking(1, 2, *pair, d=4)
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, *pair)
1 2 3 4 () {}
>>> unpacking(1, 2, *pair, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> unpacking(1, 2, c=3, *pair)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'

>>> args_list = [3]
>>> unpacking(1, 2, *args_list, d=4)
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, *args_list)
1 2 3 4 () {}
>>> unpacking(1, 2, c=3, *args_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> unpacking(1, 2, *args_list, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'


>>> pair = (3, 4)
>>> unpacking(1, 2, *pair)
1 2 3 4 () {}
>>> unpacking(1, 2, 3, 4, *pair)
1 2 3 4 (3, 4) {}
>>> unpacking(1, 2, d=4, *pair)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, *pair, d=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'



>>> args_list = [3, 4]
>>> unpacking(1, 2, *args_list)
1 2 3 4 () {}
>>> unpacking(1, 2, 3, 4, *args_list)
1 2 3 4 (3, 4) {}
>>> unpacking(1, 2, d=4, *args_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, *args_list, d=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'


>>> arg_dict = {'c':3, 'd':4}
>>> unpacking(1, 2, **arg_dict)
1 2 3 4 () {}
>>> arg_dict = {'d':4, 'c':3}
>>> unpacking(1, 2, **arg_dict)
1 2 3 4 () {}
>>> arg_dict = {'c':3, 'd':4, 'not_a_parameter': 75}
>>> unpacking(1, 2, **arg_dict)
1 2 3 4 () {'not_a_parameter': 75}


>>> unpacking(1, 2, *pair, **arg_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, 3, 4, **arg_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'

# Positional arguments take priority over any other form of argument passing
>>> unpacking(1, 2, **arg_dict, c=3)
1 2 3 4 () {'not_a_parameter': 75}
>>> unpacking(1, 2, 3, **arg_dict, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'

Tvingar användningen av namngivna parametrar

Alla parametrar som anges efter den första asterisken i funktionssignaturen är endast sökord.

def f(*a, b):
    pass

f(1, 2, 3)
# TypeError: f() missing 1 required keyword-only argument: 'b'

I Python 3 är det möjligt att sätta en enda asterisk i funktionssignaturen för att säkerställa att de återstående argumenten bara kan skickas med hjälp av nyckelordargument.

def f(a, b, *, c):
    pass

f(1, 2, 3)
# TypeError: f() takes 2 positional arguments but 3 were given
f(1, 2, c=3)
# No error

Rekursiv Lambda med tilldelad variabel

En metod för att skapa rekursiva lambda-funktioner innefattar att tilldela funktionen till en variabel och sedan hänvisa till den variabeln i själva funktionen. Ett vanligt exempel på detta är den rekursiva beräkningen av faktorn för ett nummer - som visas i följande kod:

lambda_factorial = lambda i:1 if i==0 else i*lambda_factorial(i-1)
print(lambda_factorial(4)) # 4 * 3 * 2 * 1 = 12 * 2 = 24

Beskrivning av kod

Lambda-funktionen ges genom sitt variabla tilldelning ett värde (4) som den utvärderar och returnerar 1 om det är 0 eller annars returnerar det nuvarande värde ( i ) * en annan beräkning med lambda-funktionen för värdet - 1 ( i-1 ). Detta fortsätter tills det överförda värdet minskas till 0 ( return 1 ). En process som kan visualiseras som:

recursive_lambda_path



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow