Thread View: pl.comp.programming
5 messages
5 total messages
Started by Roman Tyczka
Wed, 17 Feb 2021 09:44
Python i argumenty funkcji
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 09:44
Date: Wed, 17 Feb 2021 09:44
40 lines
2408 bytes
2408 bytes
Uczę się Pythona, trochę już ogarniam, ale trafiłem na niejasny dla mnie
przypadek. Wiem mniej więcej o co chodzi z parametrami w funkcjach typu
pozycyjnego i nazwanego (tuple i dictionary), ale nie rozumiem w
poniższym kodzie czegoś.
Jest oto klasa DESCipher:
class DESCipher(blockalgo.BlockAlgo):
"""DES cipher object"""
def __init__(self, key, *args, **kwargs):
"""Initialize a DES cipher object
See also `new()` at the module level."""
blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs)
[...]
W ostatniej linii woła ona metodę __init__() klasy BlockAlgo:
class BlockAlgo:
"""Class modelling an abstract block cipher."""
def __init__(self, factory, key, *args, **kwargs):
self.mode = _getParameter('mode', 0, args, kwargs,
default=MODE_ECB)
[...]
Ta klasa z kolei woła metodę _getParameter().
I teraz dlaczego w wywołaniu metody __init__ parametry są przekazane w
formie jak w definicji czyli *args, **kwargs? W przykładach jakie
widziałem, a także w wywołaniu _getParameter() są już podane zwyczajnie,
czyli: args, kwargs.
Skąd w tym pierwszym wywołaniu i dlaczego są użyte gwiazdki (czyli w
formie takiej jak w definicji metody/funkcji)?
--
pzdr
Roman
Re: Python i argumenty funkcji
Author: Maciek Godek
Date: Wed, 17 Feb 2021 11:40
Date: Wed, 17 Feb 2021 11:40
102 lines
4005 bytes
4005 bytes
środa, 17 lutego 2021 o 10:44:33 UTC+1 Roman Tyczka napisał(a):
> Uczę się Pythona, trochę już ogarniam, ale trafiłem na niejasny dla mnie
> przypadek. Wiem mniej więcej o co chodzi z parametrami w funkcjach typu
> pozycyjnego i nazwanego (tuple i dictionary), ale nie rozumiem w
> poniższym kodzie czegoś.
>
> Jest oto klasa DESCipher:
>
>
> class DESCipher(blockalgo.BlockAlgo):
> """DES cipher object"""
>
> def __init__(self, key, *args, **kwargs):
> """Initialize a DES cipher object
>
> See also `new()` at the module level."""
> blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs)
> [...]
>
> W ostatniej linii woła ona metodę __init__() klasy BlockAlgo:
>
> class BlockAlgo:
> """Class modelling an abstract block cipher."""
>
> def __init__(self, factory, key, *args, **kwargs):
> self.mode = _getParameter('mode', 0, args, kwargs,
> default=MODE_ECB)
> [...]
>
> Ta klasa z kolei woła metodę _getParameter().
> I teraz dlaczego w wywołaniu metody __init__ parametry są przekazane w
> formie jak w definicji czyli *args, **kwargs? W przykładach jakie
> widziałem, a także w wywołaniu _getParameter() są już podane zwyczajnie,
> czyli: args, kwargs.
> Skąd w tym pierwszym wywołaniu i dlaczego są użyte gwiazdki (czyli w
> formie takiej jak w definicji metody/funkcji)?
Ściśle rzecz biorąc, dlatego, że projektant funkcji _getParameter() tak sobie postanowił.
Argumenty w Pythonie są pomyślane w taki sposób, że jak masz tę gwiazdkę, to ona przechwyci do listy dowolnie wiele argumentów. Na przykład:
def list(*x):
return x
sprawi, że jak wywołamy
list(1,2,3)
to w wyniku dostaniemy listę
(1,2,3)
Tak to wygląda w kontekście definicji. Natomiast w kontekście użycia rola gwiazdki jest analogiczna, Załóżmy, że mamy taką funkcję:
def f(x, y, z):
return [x, y, z]
i do tego mamy listę L=(1,2,3)
Moglibyśmy sobie wywołać funkcję f w taki sposób:
f(L[0], L[1], L[2])
ale jeśli zamiast tego napiszemy
f(*L)
to efekt będzie taki sam. (Oczywiście, możemy używać indeksowania jeżeli znamy ilość argumentów, którą bierze f. Natomiast w ogólnym przypadku jej nie znamy, dlatego przekazywanie argumentów przez operator gwiazdki jest ogólniejsze)
Jeżeli idzie o operator dwóch gwiazdek, to jest on analogiczny, z tą różnicą, że nie są tworzone/rozpakowywane listy, tylko słowniki, czyli np.
def dict(**kwargs):
return kwargs
sprawi, że jak napiszemy
dict(a=5,b=10)
to dostaniemy słownik
{'a': 5, 'b': 10}
I teraz jeśli mamy funkcję:
def g(a, b):
...
oraz słownik
D = {'a':5, 'b':10}
to zamiast pisać
g(a=5, b=10)
albo
g(a=D['a'], b=D['b'])
możemy napisać
g(**D)
Re: Python i argumenty funkcji
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 13:50
Date: Wed, 17 Feb 2021 13:50
51 lines
2720 bytes
2720 bytes
W dniu 17.02.2021 o 12:40, Maciek Godek pisze: >> I teraz dlaczego w wywołaniu metody __init__ parametry są przekazane w >> formie jak w definicji czyli *args, **kwargs? W przykładach jakie >> widziałem, a także w wywołaniu _getParameter() są już podane zwyczajnie, >> czyli: args, kwargs. >> Skąd w tym pierwszym wywołaniu i dlaczego są użyte gwiazdki (czyli w >> formie takiej jak w definicji metody/funkcji)? > > Ściśle rzecz biorąc, dlatego, że projektant funkcji _getParameter() tak sobie postanowił. > > Argumenty w Pythonie są pomyślane w taki sposób, że jak masz tę gwiazdkę, to ona przechwyci do listy dowolnie wiele argumentów. Na przykład: > > def list(*x): > return x > > sprawi, że jak wywołamy > > list(1,2,3) > > to w wyniku dostaniemy listę > > (1,2,3) > > Tak to wygląda w kontekście definicji. Natomiast w kontekście użycia rola gwiazdki jest analogiczna, Załóżmy, że mamy taką funkcję: > > def f(x, y, z): > return [x, y, z] > > i do tego mamy listę L=(1,2,3) > > Moglibyśmy sobie wywołać funkcję f w taki sposób: > > f(L[0], L[1], L[2]) > > ale jeśli zamiast tego napiszemy > > f(*L) > > to efekt będzie taki sam. A czy nie możemy po prostu zawołać: f(L) ? ps. skąd się wzięła powszechnie używana nazwa kwargs? kv to bym jeszcze jako key-value rozszyfrował, ale kw? -- pzdr Roman
Re: Python i argumenty funkcji
Author: Maciek Godek
Date: Wed, 17 Feb 2021 14:10
Date: Wed, 17 Feb 2021 14:10
59 lines
3570 bytes
3570 bytes
środa, 17 lutego 2021 o 14:51:13 UTC+1 Roman Tyczka napisał(a): > W dniu 17.02.2021 o 12:40, Maciek Godek pisze: > >> I teraz dlaczego w wywołaniu metody __init__ parametry są przekazane w > >> formie jak w definicji czyli *args, **kwargs? W przykładach jakie > >> widziałem, a także w wywołaniu _getParameter() są już podane zwyczajnie, > >> czyli: args, kwargs. > >> Skąd w tym pierwszym wywołaniu i dlaczego są użyte gwiazdki (czyli w > >> formie takiej jak w definicji metody/funkcji)? > > > > Ściśle rzecz biorąc, dlatego, że projektant funkcji _getParameter() tak sobie postanowił. > > > > Argumenty w Pythonie są pomyślane w taki sposób, że jak masz tę gwiazdkę, to ona przechwyci do listy dowolnie wiele argumentów. Na przykład: > > > > def list(*x): > > return x > > > > sprawi, że jak wywołamy > > > > list(1,2,3) > > > > to w wyniku dostaniemy listę > > > > (1,2,3) > > > > Tak to wygląda w kontekście definicji. Natomiast w kontekście użycia rola gwiazdki jest analogiczna, Załóżmy, że mamy taką funkcję: > > > > def f(x, y, z): > > return [x, y, z] > > > > i do tego mamy listę L=(1,2,3) > > > > Moglibyśmy sobie wywołać funkcję f w taki sposób: > > > > f(L[0], L[1], L[2]) > > > > ale jeśli zamiast tego napiszemy > > > > f(*L) > > > > to efekt będzie taki sam. > A czy nie możemy po prostu zawołać: > > f(L) > > ? > Jak napiszesz f(L), to wywołasz f z jednym argumentem, mianowicie z listą (1,2,3). (w powyższym przykładzie to będzie błąd, bo funkcja f spodziewa się trzech argumentów) Chodzi o to, że operator * przy wywołaniu funkcji rozwija listę argumentów w miejscu wywołania. Czyli jeżeli L ma 3 elementy, to f(*L) jest równoważne f(L[0], L[1], L[2]), jeżeli L ma 4 elementy, to f(*L) jest równoważne f(L[0], L[1], L[2], L[3]) i tak dalej. > ps. skąd się wzięła powszechnie używana nazwa kwargs? kv to bym jeszcze > jako key-value rozszyfrował, ale kw? od "keyword arguments"
Re: Python i argumenty funkcji
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 16:58
Date: Wed, 17 Feb 2021 16:58
24 lines
2197 bytes
2197 bytes
W dniu 17.02.2021 o 15:10, Maciek Godek pisze: > Jak napiszesz f(L), to wywołasz f z jednym argumentem, mianowicie z listą (1,2,3). > (w powyższym przykładzie to będzie błąd, bo funkcja f spodziewa się trzech argumentów) > > Chodzi o to, że operator * przy wywołaniu funkcji rozwija listę argumentów w miejscu wywołania. > Czyli jeżeli L ma 3 elementy, to f(*L) jest równoważne f(L[0], L[1], L[2]), > jeżeli L ma 4 elementy, to f(*L) jest równoważne f(L[0], L[1], L[2], L[3]) > i tak dalej. Tak! I to ma sens, dzięki, elastyczność składni pythona ciągle mnie zaskakuje :-) >> ps. skąd się wzięła powszechnie używana nazwa kwargs? kv to bym jeszcze >> jako key-value rozszyfrował, ale kw? > > od "keyword arguments" Dzięki, kolejne zagadki wyjaśnione :-) -- pzdr Roman
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads