2011-12-31 11 views
9

Czy jest to bardziej pythonic sposób to zrobić?Pythoniczny sposób przekazywania argumentów słów kluczowych warunkowo

if authenticate: 
    connect(username="foo") 
else: 
    connect(username="foo", password="bar", otherarg="zed") 
+0

Co się stało z tym, co masz? "Nie powtarzaj się" to dobra zasada do naśladowania, ale nie wtedy, gdy czyni twój kod bardziej skomplikowanym. –

+0

Nie będzie to o wiele bardziej skomplikowane, dlatego w tym przypadku cenię DRY nad złożonością. – ash

Odpowiedz

16
  1. Można dodawać je do listy kwargs tak:

    connect_kwargs = dict(username="foo") 
    if authenticate: 
        connect_kwargs['password'] = "bar" 
        connect_kwargs['otherarg'] = "zed" 
    connect(**connect_kwargs) 
    

    To może być czasami pomocne, gdy masz skomplikowany zestaw opcji, które mogą być przekazywane do funkcji. W tym prostym przypadku, myślę, że to, co masz jest lepsze, ale to może być uznane za więcej pythonic, ponieważ nie powtarza się username="foo" dwa razy jak OP.

  2. Tego alternatywnego podejścia można również użyć, mimo że działa tylko wtedy, gdy wiesz, jakie są domyślne argumenty. Nie uważam też, że jest to bardzo "pytonowe" ze względu na zduplikowane klauzule if.

    password = "bar" if authenticate else None 
    otherarg = "zed" if authenticate else None 
    connect(username="foo", password=password, otherarg=otherarg) 
    
+0

+1 Chciałbym opublikować to samo. –

+2

Opcja 1 jest dobra, opcja 2 nie jest. –

+0

Opcja 1 to więcej linii i mniej prosto niż pierwotne pytanie =/ – Charlie

-2

Albo, bardziej zwięźle:

connect(**(
    {'username': 'foo', 'password': 'bar', 'otherarg': 'zed'} 
    if authenticate else {'username': 'foo'} 
)) 
+1

Jak to jest bardziej zwięzłe? – jterrace

+0

Jest to pojedyncze wyrażenie, które unika powtarzających się odwołań do tymczasowego dla gromadzenia argumentów do przekazania. –

+0

Mam na myśli w odniesieniu do oryginału. Jest to dokładnie to samo, co OP, tylko uporządkowane. – jterrace

0

Pomyślałem, że rzucam mój kapelusz w ringu:

authenticate_kwargs = {'password': "bar", 'otherarg': "zed"} if authenticate else {} 
connect(username="foo", **authenticate_kwargs) 
2

wersja PO jest naprawdę w porządku w tym przypadku gdzie liczba bezwarunkowych argumentów jest niska w porównaniu do liczby warunków warunkowych. Jest tak dlatego, że tylko bezwarunkowe argumenty muszą być powtórzone w obu gałęziach konstrukcji if-else. Często jednak napotykam na przeciwną sytuację, tzn. Liczba bezwarunkowych argumentów jest wysoka w porównaniu z liczbą warunków warunkowych.

To co mam użyć:

connect(username="foo", 
     **(dict(password="bar", otherarg="zed") if authenticate else {})) 
Powiązane problemy