Powiedzmy, że mam listę argumentów całkowitych w funkcji i chcę dodać 1 do każdego z nich. Czy istnieje czysty sposób działania, coś w rodzaju tego pseudo-kodu:

def foo(a, b, c):
    for argument in arguments:
        argument += 1
    ...

W szczególności chcę uniknąć wyraźnie odwoływania się do każdego z tych argumentów wewnątrz kodu, i po prostu itera przed wszystkimi argumentami. Zmiana argumentów funkcji do listy nie jest opcją, ponieważ a, b, c ma określone znaczenie w kodzie.

3
Daniyal Shahrokhian 26 czerwiec 2017, 04:05

3 odpowiedzi

Najlepsza odpowiedź

Z wyraźne odniesienie

W drodze do zrobienia Clean prawdopodobnie używa iterable rozpakowania i mapowania, jak:

def foo(a,b,c):
    a,b,c = map(lambda x:x+1,(a,b,c))
    # ...

Lub za zaokrąglanie:

 def foo(a,b,c):
     a,b,c = map(round,(a,b,c))
     # ...

Ponieważ jest to nadal wyraźne , a ponadto utrzymuje parametry w podpisie funkcji foo.

Możesz oczywiście użyć *args i **kwargs i manipuluj te (bezpośrednio), ale może to spowodować utratę informacji o tym, co parametry a, b i c } Średnia (ich semantyka).

Korzystanie z Decorator (Zastosuj funkcję na parametrach Wszystkie )

Innym sposobem, aby to zrobić, co usunie semantykę parametrów używa dekorator :

def apply_func_args(func):
    def dec(f):
        def g(*args,**kwargs):
            return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
        g.__name__ = f.__name__
        g.__doc__ = f.__doc__
        return g
    return dec

Wtedy możesz umieść dekorator na foo , jak:

@apply_func_args(round)
def foo(a,b,c):
    # ...

Teraz, jeśli zadzwonisz foo(1.4,1.3,1.9), foo otrzyma (a,b,c) == (1,1,2). Na przykład, jeśli chcesz print a, b i c:

>>> def apply_func_args(func):
...     def dec(f):
...         def g(*args,**kwargs):
...             return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
...         g.__name__ = f.__name__
...         g.__doc__ = f.__doc__
...         return g
...     return dec
... 
>>> @apply_func_args(round)
... def foo(a,b,c):
...     print((a,b,c))
... 
>>> foo(1.4,1.3,1.9)
(1, 1, 2)
>>> foo(1.4,2.5,c=0)
(1, 2, 0)
>>> foo(b=1.4,a=2.5,c=0)
(2, 1, 0)

Oto więc zdefiniowaliśmy czysty sposób na zastosowanie funkcji (round) na wszystko o nazwie i nienazwanych parametrach foo. W rezultacie, jeśli zadzwonisz foo, foo zawsze otrzyma zaokrąglone wartości.

3
Willem Van Onsem 26 czerwiec 2017, 19:11

Oto przykład bez skutków ubocznych:

a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
c = [9, 8, 7, 6]
def foo(*args):
    modified = list()
    for idx, arg in enumerate(args):
        modified.append([x + 1 for x in arg])
    print modified
    # do something else

# In [17]: foo(a, b, c)
# [[2, 3, 4, 5], [6, 7, 8, 9], [10, 9, 8, 7]]

Dzięki tej implementacji możesz wprowadzić tyle tablic, ile chcesz.

0
aquil.abdullah 26 czerwiec 2017, 01:58
def foo(a, b, c):
    return call_other(round(a),round(b),round(c))

Lub

def foo(a, b, c):
    return call_other(a+1,b+1,c+1)

Myślę, że jeśli rozumiem, co próbujesz zrobić ... (od czytania komentarzy)

2
Joran Beasley 26 czerwiec 2017, 01:18