Possible Duplicate:
What is the Python equivalent of static variables inside a function?
I try to write a recursive function. It iterates over a vector and gives a value which depends upon current value and previous value. In Matlab I can declare a variable as persistent
inside the function and the value is stored in memory after the function is called, so next call of the function start from the previous values.
This is what i started for simple moving average:
def AvgFilter(x):
if not firstRun: # checks if runs for first time, i.e. firstRun is empty
k = 1 # setup initial variables if run for first time
prevAvg = 0 # prevAvg - the average calculated during last call
firstRun = 1 # only for initialisation
alpha = (k-1)/k
avg = alpha * prevAvg + (1 - alpha)*x
prevAvg = avg
k = k + 1
return avg
I need the variables k
prevAvg
firstRun
to be remembered between function calls. I read it can be done via decorator, I did try to implement it seting @counter
before function but not sure how I should implement it. Is decorator the only way (did not find anything else)? and how to write counter function to store my variables? I bit worry that later on with more complicated recursions I will be completely lost with the idea of decorator.
Python doesn't have static variables but you can fake it by defining a callable class object and then using it as a function. Also see this answer. Note that __call__ makes an instance of a class (object) callable by its own name. That's why calling foo() above calls the class' __call__ method.
A persistent variable is a local variable in a MATLAB® function that retains its value in memory between calls to the function. If you generate code from your model, you must initialize a persistent variable for your MATLAB functions. For more information, see persistent .
The persistent values can be stored in a variety of locations, locally or in the cloud. Values can either be retrieved from a single location or can be aggregated from multiple locations. Persistent values are used, for example, to support web sessions, and also for general system initialization.
Sounds like a job for generators! Generators let you pretend you're just calculating the values one at a time in a loop, but it will actually pause execution and return a value when you call yield
.
def AvgFilter():
k = 1
avg = 0
while True:
alpha = (k-1)/float(k)
x = yield avg # yield/return the old average, and get the new input value
avg = alpha * avg + (1 - alpha)*x
k = k + 1
f = AvgFilter()
print f.next()
print f.send(1)
print f.send(2)
print f.send(20)
print f.send(20)
# 0
# 1.0
# 1.5
# 7.66666666667
# 10.75
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With