Python Language
funktioner
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
- Mer om funktioner och dekoratörer: https://www.thecodeship.com/patterns/guide-to-python-function-decorators/
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, annarsTypeError
enTypeError
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
ochkwarg2
är valfria. Om värdet ska ändras gäller samma regler som förarg1
(antingen position eller nyckelord) ochkwarg1
(endast nyckelord). -
*args
fångar ytterligare positionsparametrar. Men notera attarg1
ocharg2
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 ärarg1
,arg2
,kwarg1
ellerkwarg2
. 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. Exempelvismath.isclose
funktionen i Python 3.5 och högre meddef 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 uttryckligtdef
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.
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: