简体   繁体   English

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

[英]Where does the 'self' come from? Putting a member function as target for threading.Thread

in the following code 在以下代码中

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

I am using the member function of an instantiated object as target for the thread. 我使用实例化对象的成员函数作为线程的目标。 I was wondering why it works, ie does the threading module do something special to detect if there is a member function (as opposed to a "normal" function w/o object context) at the other end of the callable-Reference? 我想知道为什么它的工作原理,即线程模块是否做了一些特殊的事情来检测是否有一个成员函数(而不是对象上下文中的“普通”函数)与callable-Reference的另一端? I think the usual callback mechanism like in ftplib.retrlines() et al will only accept plain global functions. 我认为像ftplib.retrlines()等人那样的通常回调机制只接受普通的全局函数。 Is it better to stay away from this alltogether? 最好远离这一切吗?

slarti slarti

PS: coming from C/C++ the exposed behaviour is new to me (although welcome). PS:来自C / C ++,暴露的行为对我来说是新的(尽管欢迎)。

You might want to read about Python's method objects . 您可能想要阅读Python的方法对象

Python's self is sort of like C++'s this , except you have to put it in the method declaration. Python的self是有点像C ++的this ,除非你必须把它在方法声明。

What happens that when you declare a function inside a class, it “becomes” a method . 当你在一个类中声明一个函数时,它会变成一个方法 When you get a method of an object, it becomes a bound method , which has the first argument ( self ) fixed to the object you got it from. 当你得到一个对象的方法时,它就变成了一个绑定方法 ,它将第一个参数( self )固定到你得到它的对象上。

Try: 尝试:

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

No extra magic is happening in your Threading case, it's just regular Python. 在你的线程案例中没有发生额外的魔法,它只是普通的Python。

foo1.do and foo2.do are bound methods. foo1.dofoo2.do是绑定方法。

I suggest you look at the following documentation links: 我建议你看一下以下文档链接:

Excerpt from the second link: 摘自第二个链接:

When a bound user-defined method object is called, the underlying function (im_func) is called, inserting the class instance (im_self) in front of the argument list. 当调用绑定的用户定义的方法对象时,将调用基础函数(im_func),将类实例(im_self)插入参数列表的前面。 For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling xf(1) is equivalent to calling Cf(x, 1). 例如,当C是包含函数f()的定义的类,而x是C的实例时,调用xf(1)相当于调用Cf(x,1)。

Suppose you wrote the same class in C++: 假设您在C ++中编写了相同的类:

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

foo f = foo(42);

Here &foo::do would be a pointer to member function and you would need a foo instance to be able to call it. 这里&foo::do将是一个指向成员函数的指针,你需要一个foo实例才能调用它。 Suppose you could pass around f.do : then you wouldn't need anything else to call do() on f . 假设你可以传递f.do :那么你就不需要在f上调用do()了。 This is exactly what a bound member is in Python and by passing foo1.do you are passing both the method to call and the instance onm which to call it. 这正是绑定成员在Python中的作用,并通过传递foo1.do您将传递方法调用和实例onm调用它。

This same problem has been addressed in C++ either with proprietary extensions, such as Borland's closures, or with libraries, such as Boost.Bind . C ++也解决了同样的问题,无论是使用专有扩展(如Borland的闭包),还是使用库(如Boost.Bind)

In any instance (non-static) method in a class, the method should be using some variables in the instance of the class thats its running in right? 在类的任何实例(非静态)方法中,该方法应该在其运行的类的实例中使用一些变量吗? So, every instance method needs a copy the object thats running it to access these variables. 因此,每个实例方法都需要复制运行它的对象来访问这些变量。 That is what self is, a copy of the object thats running the method. 这就是self是运行该方法的对象的副本。

In most languages, its implicitly a parameter in instance methods (so you don't really need to write out self in the method, but its there , but in python its explicitly shown, so you have a parameter called self` in every instance method. It does not change anything, it's just a sort of more obvious way of showing whats happening. 在大多数语言中,它隐式地是实例方法中的一个参数(所以你不需要在方法中写出self ,但它在那里, but in python its explicitly shown, so you have a parameter called在每个实例方法中, but in python its explicitly shown, so you have a parameter called self` , but in python its explicitly shown, so you have a parameter called它没有改变任何东西,它只是一种更明显的方式来显示发生了什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM