2015-07-08 10 views
6

mi hanno spesso dichiarazioni nel mio codice che effettuare le seguenti operazioni:Mutating/in-place funzione di invocazione o adattamento in Python

long_descriptive_variable_name = some_function(long_descriptive_variable_name) 

che è molto chiaro, ma verbose e un po 'ridondante, allo stesso tempo. C'è qualche modo in Python per semplificare questa affermazione, forse facendo sì che some_function funzioni come una funzione "mutante" ("in-place")?

Ad esempio, nel Julia one can often do seguente:

some_function!(long_descriptive_variable_name) 

e questo viene inviato alla versione di some_function che scrive direttamente long_descriptive_variable_name, l'aggiornamento in modo efficace la variabile.

Esiste un modo per esprimere in modo conciso lo stesso in Python per una funzione generica some_function?

Che ne dici di fare lo stesso con un metodo di oggetto generale? vale a dire facilitandone

long_variable_name = long_variable_name.method(arg1, arg2) 

Se quanto sopra non è (facilmente) fattibile con le attuali versioni di Python, ci sono delle persone politicamente esposte considerando questo cambiamento nel prossimo futuro?

+0

Non penso che ci sia stato un modo diretto per tali compiti, ma è possibile creare una variabile 'global' all'interno della propria funzione e assegnare il risultato di ritorno a quello. – Kasramvd

risposta

1

Quello che stai chiedendo può essere realizzato in questo modo, ma io di certo non lo consiglio a farlo:

>>> x = 10 
>>> def foo(func, string_of_var): 
    globals()[string_of_var] = func(globals()[string_of_var]) 

>>> def bar(x): 
    return x * 2 

>>> foo(bar, 'x') 
>>> x 
20 

Per quanto riguarda un PEP per cambiarlo se ce n'è uno dubito che sarebbe ottenere approvato . Chiamare una funzione come questa che cambia in modo implicito un valore va contro lo Zen di Python:

The Zen of Python, by Tim Peters 

Beautiful is better than ugly. 
Explicit is better than implicit. <==== Relevant line 
Simple is better than complex. 
Complex is better than complicated. 
Flat is better than nested. 
Sparse is better than dense. 
Readability counts. 
Special cases aren't special enough to break the rules. <==== also probably relevant 
Although practicality beats purity. 
Errors should never pass silently. 
Unless explicitly silenced. 
In the face of ambiguity, refuse the temptation to guess. 
There should be one-- and preferably only one --obvious way to do it. 
Although that way may not be obvious at first unless you're Dutch. 
Now is better than never. 
Although never is often better than *right* now. 
If the implementation is hard to explain, it's a bad idea. <==== And this one for good measure 
If the implementation is easy to explain, it may be a good idea. 
Namespaces are one honking great idea -- let's do more of those! 

Anche questo sarebbe probabilmente comporterà una buona dose di lavoro senza aggiungere molto alla lingua. Python non ha un ++/-- per this reason. Sarebbe stato più lavoro aggiungerlo quando lo x += 1 ottiene la stessa cosa. Lo stesso è vero qui, ci vorrebbe una quantità non trascurabile di lavoro da parte di più persone per farti risparmiare qualche colpo di chiave quando chiami le funzioni.

0

ESCLUSIONE DI RESPONSABILITÀ: questo non deve essere utilizzato in alcun codice serio, l'ho scritto solo per divertimento e non penso nemmeno che sia intelligente.

Non so se questo è quello che volevi (quindi perdonami se è fuori tema), ma mi sono davvero divertito durante la creazione di questo.

class FancyThing(object): 

    def __init__(self, value): 

     self.value = value 

    def update(self, callback): 

     self.value = callback(self.value) 

    def __get__(self, instance, owner): 

     return instance.value 

    def __set__(self, instance, value): 

     instance.value = value 

    def __str__(self): 

     return str(self.value) 

    def __add__(self, other): 

     return self.value + other 

Se si avvolgono qualcosa in questa classe, è possibile update con qualsiasi callback casuale.

def some_func(val): 
    return val * 3 

a = FancyThing(3.5) 
print a 

a.update(tester) 
print a 
b = a + 5 
print b 

Uscite:

3.5 
10.5 
15.5 

La parte divertente è che si deve definire sacco di metodi built-in per essere in grado di utilizzare il valore interno come uno normale, come ho fatto per __add__().