“自我”在哪里?来自?将成员函数作为 threading.Thread 的目标
在下面的代码中,
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()
我使用实例化对象的成员函数作为线程的目标。我想知道它为什么起作用,即线程模块是否做了一些特殊的事情来检测在另一端是否有一个 member 函数(而不是一个没有对象上下文的“正常”函数)可调用参考?我认为 ftplib.retrlines() 等中的常用回调机制仅接受普通的全局函数。是不是最好完全远离这个?
slarti
PS:来自 C/C++ 的暴露行为对我来说是新的(尽管欢迎)。
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, i.e. 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? I think the usual callback mechanism like in ftplib.retrlines() et al will only accept plain global functions. Is it better to stay away from this alltogether?
slarti
PS: coming from C/C++ the exposed behaviour is new to me (although welcome).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
foo1.do
和foo2.do
是绑定方法。我建议您查看以下文档链接:
第二个链接摘录:
foo1.do
andfoo2.do
are bound methods.I suggest you look at the following documentation links:
Excerpt from the second link:
假设您用 C++ 编写了同一个类:
这里
&foo::do
将是指向成员函数的指针,您需要一个foo
实例才能调用它。假设您可以传递f.do
: 那么您不需要任何其他东西来调用f
上的do()
。这正是 Python 中绑定成员的含义,通过传递 foo1.do ,您将传递要调用的方法和要调用它的实例。同样的问题在 C++ 中已经通过专有扩展(例如 Borland 的闭包)或库(例如 Boost.Bind。
Suppose you wrote the same class in C++:
Here
&foo::do
would be a pointer to member function and you would need afoo
instance to be able to call it. Suppose you could pass aroundf.do
: then you wouldn't need anything else to calldo()
onf
. This is exactly what a bound member is in Python and by passingfoo1.do
you are passing both the method to call and the instance onm which to call it.This same problem has been addressed in C++ either with proprietary extensions, such as Borland's closures, or with libraries, such as Boost.Bind.
在类中的任何实例(非静态)方法中,该方法应该使用其运行所在的类实例中的一些变量,对吗?因此,每个实例方法都需要运行它的对象的副本才能访问这些变量。这就是
self
,即运行该方法的对象的副本。在大多数语言中,它在实例方法中隐式地是一个参数(所以你实际上不需要在方法中写出
self
,但它在那里,但在 python 中它是显式显示的,所以你在每个实例方法中都有一个名为
self` 的参数,它不会改变任何内容,它只是显示正在发生的情况的一种更明显的方式。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.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.您可能想了解 Python 的方法对象。
Python 的 self 有点像 C++ 的 this ,只不过您必须将其放在方法声明中。
当您在类中声明一个函数时,它会“变成”一个方法,会发生什么情况。当您获取对象的方法时,它就成为绑定方法,其中第一个参数(
self
)固定为您从中获取它的对象。尝试:
在你的线程案例中没有发生额外的魔法,它只是普通的Python。
You might want to read about Python's method objects.
Python's
self
is sort of like C++'sthis
, except you have to put it in the method declaration.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.Try:
No extra magic is happening in your Threading case, it's just regular Python.