🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.programming
5 messages
5 total messages Started by Roman Tyczka Wed, 17 Feb 2021 09:44
Python i argumenty funkcji
#217402
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 09:44
40 lines
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
#217403
Author: Maciek Godek
Date: Wed, 17 Feb 2021 11:40
102 lines
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
#217404
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 13:50
51 lines
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
#217405
Author: Maciek Godek
Date: Wed, 17 Feb 2021 14:10
59 lines
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
#217406
Author: Roman Tyczka
Date: Wed, 17 Feb 2021 16:58
24 lines
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