使用Python函数作为类

时间:2015-10-20 13:36:30

标签: python multithreading function python-multithreading

我对Twisted python很感兴趣,正在做我的每周"保持最新和练习"阅读http://jdb.github.io/concurrent/preemptive.html

摘要: 使用 incr() incr 作为参数有什么区别?当我将函数声明为incr()时,我得到"正确"即使有大量的结果。但是,当我宣布它为incr时,我得到错误的结果。谷歌上的快速搜索只是告诉我如何在类中声明函数。

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

3 个答案:

答案 0 :(得分:2)

让我告诉你。

让我们定义一些测试功能。哪个会在被解雇时打印出来的东西

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

答案 1 :(得分:1)

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

x = function()

表示x将被设置为function运行时返回的值。但如果省略括号,则不是指返回的值,而是指函数本身。所以

x = function

表示x现在是函数,可以使用x()调用。

在您的情况下,传递incr返回的内容与函数本身之间的区别。

答案 2 :(得分:0)

在您的示例中,target=incr()将尝试在主线程中运行incr而不传递参数(即使它成功了,当它尝试使用{启动线程时也不会执行任何操作{1}} None; targetNone隐式返回的内容。使用incr运行将按预期执行线程中的递增。

使用target=incr的情况是使用闭包来避免污染全局范围。例如,在Python 3中,您可以这样做:

target=incr()

这将创建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 范围内未共享的每个线程counter;通过设置global,它会调用外部target=incr()并将包含的函数incr作为真实incr_inner返回,并使用其自己唯一的target变量。

作为闭包的嵌套主要是关于实现隐藏和简洁(并且它并不总是按照您的希望工作;在Python 2中,没有counter关键字,它无法运行写得没有一些hackery)。但是你可以在任何Python版本中从一个类中创建nonlocal个对象,并获得大致相同的“有状态线程”行为。例如:

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传递时,每个线程都保持独立的counter