“自我”来自哪里?将成员函数作为threading的目标。线程

时间:2011-10-17 08:16:25

标签: python multithreading

在以下代码中

class foo:
    def __init__(self,x):
        self.x = x

    def do(self):
        print(self.x)

foo1 = foo(1)
foo2 = foo(2)
t1=threading.Thread(target=foo1.do)
t2=threading.Thread(target=foo2.do)
t1.start()
t2.start()

我使用实例化对象的成员函数作为线程的目标。我想知道它为什么会起作用,即线程模块是否做了一些特殊的事情来检测是否有一个成员函数(而不是对象上下文的“普通”函数)可调用的参考?我认为像ftplib.retrlines()等人那样的通常回调机制只接受普通的全局函数。最好远离这一切吗?

slarti

PS:来自C / C ++,暴露的行为对我来说是新的(尽管欢迎)。

4 个答案:

答案 0 :(得分:4)

您可能想了解Python的method objects

Python的self有点像C ++的this,除非你必须把它放在方法声明中。

当你在一个类中声明一个函数时,它会变成一个方法。当你得到一个对象的方法时,它就变成了一个绑定方法,它有第一个参数(self)固定在你得到它的对象上。

尝试:

class Foo(object):
    def do(self):
        print x

instance = Foo()
print Foo.do  # prints <unbound method Foo.do>
print instance.do  # prints <bound method Foo.do of <...>>

# These are equivalent:
Foo.do(instance)
instance.do()

在你的线程案例中没有发生额外的魔法,它只是普通的Python。

答案 1 :(得分:2)

foo1.dofoo2.do是绑定方法。

我建议您查看以下文档链接:

摘自第二个链接:

  

当调用绑定的用户定义方法对象时,底层   函数(im_func)被调用,插入类实例(im_self)   在参数列表前面。例如,当C是一个类时   包含函数f()的定义,x是C的实例,   调用x.f(1)等同于调用C.f(x,1)。

答案 2 :(得分:1)

假设您在C ++中编写了相同的类:

class foo {
    int x;
  public:
    foo(int x_) { x = x_; }
    void do() { std::cout << x; }
}

foo f = foo(42);

这里&foo::do是指向成员函数的指针,你需要一个foo实例才能调用它。假设你可以传递f.do:那么你就不需要在do()上呼叫f了。这正是绑定成员在Python中的作用,并通过传递foo1.do您传递的方法和要调用它的实例onm。

C ++也解决了同样的问题,无论是使用专有扩展,例如Borland的闭包,还是使用库,例如​​Boost.Bind

答案 3 :(得分:0)

在类中的任何实例(非静态)方法中,该方法应该在其运行的类的实例中使用一些变量吗?因此,每个实例方法都需要复制运行它的对象来访问这些变量。这就是self是运行该方法的对象的副本。

在大多数语言中,它隐式地是实例方法中的一个参数(所以你不需要在方法中写出self,而是在每个实例方法中都有, but in python its explicitly shown, so you have a parameter called self`。它不会改变任何东西,它只是一种更明显的方式来显示发生的事情。