Reputation: 323
I'm looking for a way to pass function arguments through another function, in a manner identical to Stackless' tasklet
instantiation:
stackless.tasklet(function_being_called)(*args)
So far the best way I've come up with is:
mylib.tasklet(function_being_called,*args)
which works, but is not identical to Stackless' syntax. I'm not sure where to look in the documentation to find out how to accomplish this (hence the rather ambiguous title for this question). Is this even possible, or is it part of Stackless' changes to the interpreter?
EDIT: I'm now aware that there is an approach which will work for functions, but I'm unsure if it will work in my case. I'm using the greenlet library: greenlet threads obtain args when the greenlet is switch()
ed to, not on instantiation. Calling them as shown below results in
TypeError: 'greenlet.greenlet' object is not callable
.
Using greenlet.greenlet(function(args))
(still not right syntax) executes immediately and still requires args in the switch()
method. Hence I currently store variables in-class, using the syntax shown above, to pass when calling switch()
. Hope this doesn't change the question too much!
As requested, here is the code in question. First, a variant on eri's answer (DISCLAIMER: I've never used decorators before):
import greenlet # Background "greenlet" threadlet library
_scheduled = [] # Scheduler queue
def newtasklet(func): # Returns a greenlet-making function & switch() arguments.
def inner(*args,**kwargs):
newgreenlet = greenlet.greenlet(func,None)
return newgreenlet,args,kwargs
return inner
class tasklet():
def __init__(self,function=None):
global _scheduled
initializer = newtasklet(function)
self.greenlet,self.variables,self.kvars = initializer()
_scheduled.append(self)
self.blocked = False
tasklet(print)("A simple test using the print function.")
Traceback (most recent call last):
File "<pyshell#604>", line 1, in <module>
tasklet(print)("A simple test using the print function.")
TypeError: 'tasklet' object is not callable
Original code (working but not syntactically ideal):
class tasklet():
def __init__(self,function=None,*variables,parent=None):
global _scheduled
self.greenlet = greenlet.greenlet(function,parent)
self.variables = variables
_scheduled.append(self)
self.blocked = False
>>> tasklet(print,"A simple test using the print function.")
<__main__.tasklet object at 0x7f352280e610>
>>> a = _scheduled.pop()
>>> a.greenlet.switch(*a.variables)
A simple test using the print function.
Upvotes: 1
Views: 1830
Reputation: 1286
I'm not familiar with Stackless, but what's happening there is that the tasklet
functions returns a reference to the function, that is then called by the interpreter with the *args.
An example:
def return_the_method(method):
return method
def add_two(num1, num2):
return num1 + num2
If you have this, then run return_the_method(add_two)(1, 2)
, you'll get 3
.
Upvotes: 1
Reputation: 1
import greenlet # Background "greenlet" threadlet library
_scheduled = [] # Scheduler queue
def newtasklet(func): # Returns a greenlet-making function & switch() arguments. def inner(*args,**kwargs): newgreenlet = greenlet.greenlet(func,None) return newgreenlet,args,kwargs return inner
class tasklet(): def init(self,function=None): global _scheduled initializer = newtasklet(function) self.greenlet,self.variables,self.kvars = initializer() _scheduled.append(self) self.blocked = False def call(self, function=None): return function
def imprime(a): print a
tasklet(imprime)("A simple test using the print function.")
Upvotes: 0
Reputation: 334
Just make sure to return a function from mylib.tasklet
:
>>> def call_me(func):
# do something here, like spawn a thread
return func
>>> def being_called(str1, str2, str3):
print str1
print str2
print str3
>>> call_me(being_called)('a', 'b', 'c')
a
b
c
Upvotes: 1
Reputation: 3514
stackless.tasklet is decorator. Rewrite your function as decorator.
def tasklet(f):
def inner(*args,**kwargs):
t= Thread(target=f,args=args,kwargs=kwargs)
t.start()
return t
return inner
task=tasklet(your_func)(arg)
task.join()
It runs your_func in separate thread and returns thread instance.
Upvotes: 1
Reputation: 5186
I've never used stackless before, but stackless.tasklet(function_being_called)
is returning a function object that is being given the parameters (*args)
. If you want the syntax to be the same for your tasklet, then mylib.tasklet
should return a function.
For example:
def inner(*args):
print '|'.join(args)
def foo(func):
return func
foo(inner)('hello', 'world')
Outputs:
hello|world
Upvotes: 0