I would like to extract data from an inner function and build a generator to pass this data somewhere else.
I have the following code:
def process_func(x):
# how to construct a generator out of all arguments passed
# to this function in the consecutive calls?
print(f"processing {x}")
return True
def save_func(x):
print(f'saving {x}')
# don't edit
def read_data_and_apply_func(func):
for x in range(5):
func(x)
# don't edit
def save_data(generator, save_func):
for i in generator:
save_func(i)
def main():
generator = () # generator should contain all data passed in all read_data_and_apply_func
read_data_and_apply_func(process_func)
save_data(generator, print)
main()
how do I edit just the main function (and maybe process_func) so that I can pass the data from the inside of read_data_and_apply_func to save_data?
I tried writing code like this:
def create_generator(read_data_and_apply_func, process_func):
def generator():
for x in read_data_and_apply_func(generator.send):
yield x
return generator
def main():
generator = create_generator(read_data_and_apply_func, process_func)
generator_instance = generator()
save_data(generator_instance)
and a few similar snippets but neither of them worked.
I think the desired output should be:
processing 0
saving 0
processing 1
saving 1
processing 2
saving 2
processing 3
saving 3
processing 4
saving 4
Here's one way. This doesn't interleave the output lines.
class Holder:
def __init__(self,hdlr):
self.data = []
self.hdlr = hdlr
def add(self,i):
self.data.append(i)
self.hdlr(i)
def __iter__(self):
return iter(self.data)
def process_func(x):
print(f"processing {x}")
return True
def save_func(x):
print(f'saving {x}')
# don't edit
def read_data_and_apply_func(func):
for x in range(5):
func(x)
# don't edit
def save_data(generator, save_func):
for i in generator:
save_func(i)
def main():
generator = Holder(process_func)
read_data_and_apply_func(generator.add)
save_data(generator, save_func)
main()
Related
This is my nested functions code
def get_id():
for i in range(1,100):
pass
return i
def get_id_mysql(x):
print(x)
variable = get_id()
get_id_mysql(variable)
this function get_id return ( output : 1 ) and loop stop.. how can I hand over full loop? I mean 1,2,3..99
I Found solutions
def get_id():
t = []
for i in range(1,100):
t.append(i)
return t
def get_id_mysql(x):
for i in x:
print(i)
variable = get_id()
get_id_mysql(variable)
def MainCount(f):
def progFirst(*args,**kwargs):
progFirst.calls+=1
return f(*args,**kwargs)
progFirst.calls=0
return progFirst
#MainCount
def progSecond(i):
return i+1
#MainCount
def Count(i=0,j=1):
return i*j+1
print(progSecond.calls)
for n in range(5):
progSecond(n)
Count(j=0,i=1)
print(Count.calls)
Output :0
1
As per my understanding MainCount(probSecond) but I am not understant then how probSecond.calls equal to zero same in Count.calls also
As You Can See in MainCount function probFirst.Calls is attribute of function .When MainCount(probSecond) Now probSecond.calls is also attribute of MainCount function.
# A Python example to demonstrate that
# decorators can be useful attach data
# A decorator function to attach
# data to func
def attach_data(func):
func.data = 3
return func
#attach_data
def add (x, y):
return x + y
# Driver code
# This call is equivalent to attach_data()
# with add() as parameter
print(add(2, 3))
print(add.data)
I want to test if delete a LinkList's head element fast than add an element to LinkList's end.
This is my LinkList's main code:
class LNode:
def __init__(self,elem,next_=None):
self.elem=elem
self.next=next_
class LinkList:
def __init__(self):
self.__head=None
#delete head element
def head_pop(self):
if self.__head is None:
raise LinkedListUnderflow("in pop")
e=self.__head.elem
self.__head=self.__head.next
return e
#add an element at end
def append(self,elem):
if self.__head is None:
self.__head=LNode(elem)
return
p=self.__head
while p.next is not None:
p=p.next
p.next=LNode(elem)
import time
#test time
def timetest(f):
start=time.clock()
for a in range(0,1000000):
f
end=time.clock()
print("times:"+str(end-start))
then,I try this:
llist=LinkList()
def append():
llist.append(666)
def head_pop():
llist.head_pop()
timetest(append())
timetest(head_pop())
Output:
times:0.029582597002445254
times:0.03032071299821837
As you can see, they cost same time.
But I think it should be O(n):O(1).
What you're doing is passing the result of append() to your time test function, whereas you want to pass the function itself!
Change your time-test to call the f function:
def timetest(f):
start=time.clock()
for a in range(0,1000000):
f() # <- note the () here
end=time.clock()
print("times:"+str(end-start))
Then use this to test:
timetest(append)
timetest(head_pop)
As you can see, we're passing in the function for the test to call, instead of the RESULT of the function (being called once!)
So here's an extension to this question: https://stackoverflow.com/a/37568895/2290820
on how to optionally Enable or Disable Decorator on a Function.
On those lines, I came up with something like this to make decorator get invoked on a recursive call:
def deco(f):
def fattr(attr):
f.attr = attr
def closure(*args):
f(*args)
f.unwrap = f
f.closure = closure
return f
return fattr
#deco
def printa(x):
if x > 1:
print x
return printa(x-1)
else:
print x
return
printa({1:1})(5)
# do the same call w/o deocorator
def finta(x):
if x > 1:
print x
return finta(x-1)
else:
print x
return
finta(5) # this works
to experiment with decorators on a recursive function. Clearly, printa recursive version is not behaving the way it should be.
I could do
g = printa({1:1})
g.closure(5)
to turn on the decorator option or not use that option. Anyway, regardless of good or bad design, How can I make decorator get invoked on a recursive call?
In your deco you have an assignment f.attr = attr that "eats" your argument after first recursive call. Your should modify your recursive call this way:
def deco(f):
def fattr(attr):
f.attr = attr
def closure(*args):
f(*args)
f.unwrap = f
f.closure = closure
return f
return fattr
#deco
def printa(x):
if x > 1:
print x
return printa(None)(x-1) # None will be assigned to f.attr
else:
print x
return
printa({1:1})(5)
5
4
3
2
1
I want to get inner function result so i code it like
def main():
def sub():
a = 1
print a
exec main.__code__.co_consts[1]
using above code working successfully but i want to pass the argument to the sub function like...
def main():
def sub(x):
a = x + 1
return a
ans = exec main.__code__.co_consts[1]
print ans
in that problem is i don't know how to pass that x value.
that work must need to exec so that how to pass that x value with exec without interaction of main function
Maybe something like the code below, as suggested by this SO answer
def main():
def sub():
a = x + 1
print a
return a
exec(main.__code__.co_consts[1], {'x': 1} )