1

我正在寻找一种通过另一个函数传递函数参数的方法,其方式与 Stackless 的tasklet实例化相同:

stackless.tasklet(function_being_called)(*args)

到目前为止,我想出的最好方法是:

mylib.tasklet(function_being_called,*args)

这有效,但与 Stackless 的语法不同。我不确定在哪里查看文档以了解如何完成此操作(因此这个问题的标题相当模糊)。这是否可能,或者它是 Stackless 对解释器的更改的一部分?

编辑:我现在知道有一种方法适用于函数,但我不确定它是否适用于我的情况。我正在使用greenlet库:greenlet线程在编辑greenlet时获取args switch(),而不是在实例化时。如下所示调用它们会导致

TypeError: 'greenlet.greenlet' object is not callable.

使用greenlet.greenlet(function(args))(仍然不是正确的语法)会立即执行,并且仍然需要switch()方法中的 args。因此,我目前使用上面显示的语法将变量存储在类中,以便在调用switch(). 希望这不会改变太多的问题!

根据要求,这是有问题的代码。首先,eri 的答案的一个变体(免责声明:我以前从未使用过装饰器):

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

原始代码(工作但在语法上不理想):

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.
4

5 回答 5

1

我不熟悉 Stackless,但那里发生的情况是tasklet函数返回对该函数的引用,然后解释器使用 *args 调用该引用。

一个例子:

def return_the_method(method):
    return method

def add_two(num1, num2):
    return num1 + num2

如果你有这个,然后运行return_the_method(add_two)(1, 2),你会得到3.

于 2013-08-13T21:44:08.757 回答
1

stackless.tasklet 是装饰器。将你的函数重写为装饰器。

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()

它在单独的线程中运行 your_func 并返回线程实例。

于 2013-08-13T21:45:22.633 回答
1

只需确保从以下位置返回一个函数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
于 2013-08-13T21:46:28.607 回答
0

import greenlet # 背景“greenlet”线程库

_scheduled = [] # 调度队列

def newtasklet(func): # 返回一个生成greenlet的函数和switch()参数。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称呼 (self, function=None): 返回函数

def imprime(a): 打印一个

tasklet(imprime)("使用打印功能的简单测试。")

于 2014-08-07T21:16:28.530 回答
0

我以前从未使用过无堆栈,但stackless.tasklet(function_being_called)正在返回一个被赋予参数的函数对象(*args)。如果您希望 tasklet 的语法相同,mylib.tasklet则应返回一个函数。

例如:

def inner(*args):
    print '|'.join(args)

def foo(func):
    return func

foo(inner)('hello', 'world')

输出:

hello|world
于 2013-08-13T21:43:41.357 回答