使用Python函数作为类

2024-09-26 18:18:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Twisted python很感兴趣,每周都在http://jdb.github.io/concurrent/preemptive.html上阅读“保持最新并练习”。你知道吗

摘要: 使用incr()incr作为参数有什么区别?当我将函数声明为incr()时,即使使用大的数字,也会得到“正确”的结果。然而,当我宣布它为incr时,我得到了错误的结果。在google上的快速搜索只是向我展示了如何在类中声明函数。你知道吗

Thread(target=incr, args=(i,))

以及

Thread(target=incr(), args=(i,))

其中incr是:

counter = 0

def incr(num):
    global counter
    count = 0
    for i in range(1000):
        counter += 1
        print "\nWorker: {}, Counter: {}, Self-count: {} .".format(num, counter, count)

    print counter

Tags: 函数iogithubhttp声明targetcountcounter
3条回答

我给你看看。你知道吗

让我们定义一些测试函数。当它被点燃时会打印出来

>>> def test():
...     print "fired!"
... 

现在让我们来定义线程。你知道吗

>>> Thread(target=test)
<Thread(Thread-1, initial)>
>>> Thread(target=test())
fired!
<Thread(Thread-2, initial)>

你能看见吗?当您编写时,test()函数在您启动线程之前被激发。但是如果我们尝试运行这个线程会发生什么呢?你知道吗

>>> thread1.start()
fired!

很好

>>> thread2.start()
>>> 

什么都没有。这是因为当您编写Thread(target=test)时,您将测试函数的一个实例作为参数传递。写Thread(target=test())时传递test()函数执行的结果(None):)

在您的示例中,target=incr()在没有传递参数的情况下尝试在主线程中运行incr会失败(即使它成功了,当它尝试启动以None作为target的线程时,它也不会做任何事情;Noneincr隐式返回的内容)。使用target=incr运行将按预期在线程中执行递增操作。你知道吗

使用target=incr()的情况是使用闭包来避免污染全局范围。例如,在Python 3中,可以执行以下操作:

def incr():
    counter = 0

    def incr_inner(num):
        nonlocal counter
        count = 0
        for i in range(1000):
            counter += 1
            print("\nWorker: {}, Counter: {}, Self-count: {} .".format(num, counter, count))

        print(counter)
    return incr_inner

它将创建一个不在global范围内共享的每线程counter;通过设置target=incr(),它将调用外部incr,并返回封闭函数incr_inner作为实target,并带有自己唯一的counter变量。你知道吗

作为闭包的嵌套主要是关于实现隐藏和简洁性(它并不总是如您所希望的那样工作;在python2中,如果没有nonlocal关键字,就不能让它像编写的那样运行,而没有一些黑客技术)。但是您可以在任何版本的Python中从类生成callable对象,并获得大致相同的“有状态线程”行为。例如:

class incr(object):
    def __init__(self):
        self.counter = 0

    def __call__(self, num):
        count = 0
        for i in range(1000):
            self.counter += 1
            print("\nWorker: {}, Counter: {}, Self-count: {} .".format(num, self.counter, count))

        print(self.counter)

就像闭包一样,这个class可以用作参数,当作为target=incr()传递时,它为每个线程保持独立的counter。你知道吗

当您键入function()时,这些圆括号告诉Python在该位置运行该函数。所以呢

x = function()

意味着x将被设置为function运行时返回的值。但如果不使用括号,则不是指返回值,而是指函数本身。所以呢

x = function

意味着x现在是函数,可以用x()调用。你知道吗

在您的例子中,传递incr返回的内容和函数本身是有区别的。你知道吗

相关问题 更多 >

    热门问题