调用了不正确的对象方法
Incorrect object method is invoked
我有一个 python 文件,其中包含一个摘要 class 和几个子 class 。代码如下所示
# test.py
import threading
from abc import ABC, abstractmethod
class Job(object):
def __init__(self, job_name):
self.job_name = job_name
def start(self):
self.run()
self.clean_up()
@abstractmethod
def run(self):
pass
@abstractmethod
def clean_up(self):
pass
class JobA(Job):
def __init__(self):
super().__init__('job_a')
print('JobA constructed')
def run(self):
print('%s: run for %s' % (self.__str__(), self.job_name))
def clean_up(self):
print('%s: clean up for %s' % (self.__str__(), self.job_name))
class JobB(Job):
def __init__(self):
super().__init__('job_b')
print('JobB constructed')
def run(self):
print('%s: run for %s' % (self.__str__(), self.job_name))
def clean_up(self):
print('%s: clean up for %s' % (self.__str__(), self.job_name))
if __name__ == '__main__':
jobs = [JobA(), JobB()]
threads = [threading.Thread(name=job.__str__(), target=lambda: job.start()) for job in jobs]
print(threads)
for t in threads:
print('starting thread %s' % t.name)
t.start()
这段代码的输出是
JobA constructed
JobB constructed
[<Thread(<__main__.JobA object at 0x1008a8f70>, initial)>, <Thread(<__main__.JobB object at 0x1008a8d90>, initial)>]
starting thread <__main__.JobA object at 0x1008a8f70>
<__main__.JobB object at 0x1008a8d90>: run for job_b
<__main__.JobB object at 0x1008a8d90>: clean up for job_b
starting thread <__main__.JobB object at 0x1008a8d90>
<__main__.JobB object at 0x1008a8d90>: run for job_b
<__main__.JobB object at 0x1008a8d90>: clean up for job_b
虽然为JobA和JobB的对象都构造了两个线程,但是只在JobB的对象上调用start()。
我希望对数组中的不同对象调用 start()。
这段代码有没有错误?
谢谢。
我的 python 版本是 Python 3.9.7(默认,2021 年 10 月 12 日,22:38:23)[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
lambda
定义引用列表理解的循环变量 job
(即它定义了一个闭包)。当调用 lambda 时,它将解析名称 job
,它现在指的是理解的 last 元素(即作业 B)。
相反,您可以使用默认值,以便将理解的每个对象正确绑定到相应的 lambda
函数:
threads = [threading.Thread(name=job.__str__(), target=lambda j=job: j.start()) for job in jobs]
考虑以下示例代码以获得更好的可视化效果:
>>> funcs = [lambda: print(x) for x in range(3)]
>>> for f in funcs:
... f()
...
2
2
2
>>> funcs = [lambda y=x: print(y) for x in range(3)]
>>> for f in funcs:
... f()
...
0
1
2
我有一个 python 文件,其中包含一个摘要 class 和几个子 class 。代码如下所示
# test.py
import threading
from abc import ABC, abstractmethod
class Job(object):
def __init__(self, job_name):
self.job_name = job_name
def start(self):
self.run()
self.clean_up()
@abstractmethod
def run(self):
pass
@abstractmethod
def clean_up(self):
pass
class JobA(Job):
def __init__(self):
super().__init__('job_a')
print('JobA constructed')
def run(self):
print('%s: run for %s' % (self.__str__(), self.job_name))
def clean_up(self):
print('%s: clean up for %s' % (self.__str__(), self.job_name))
class JobB(Job):
def __init__(self):
super().__init__('job_b')
print('JobB constructed')
def run(self):
print('%s: run for %s' % (self.__str__(), self.job_name))
def clean_up(self):
print('%s: clean up for %s' % (self.__str__(), self.job_name))
if __name__ == '__main__':
jobs = [JobA(), JobB()]
threads = [threading.Thread(name=job.__str__(), target=lambda: job.start()) for job in jobs]
print(threads)
for t in threads:
print('starting thread %s' % t.name)
t.start()
这段代码的输出是
JobA constructed
JobB constructed
[<Thread(<__main__.JobA object at 0x1008a8f70>, initial)>, <Thread(<__main__.JobB object at 0x1008a8d90>, initial)>]
starting thread <__main__.JobA object at 0x1008a8f70>
<__main__.JobB object at 0x1008a8d90>: run for job_b
<__main__.JobB object at 0x1008a8d90>: clean up for job_b
starting thread <__main__.JobB object at 0x1008a8d90>
<__main__.JobB object at 0x1008a8d90>: run for job_b
<__main__.JobB object at 0x1008a8d90>: clean up for job_b
虽然为JobA和JobB的对象都构造了两个线程,但是只在JobB的对象上调用start()。
我希望对数组中的不同对象调用 start()。 这段代码有没有错误?
谢谢。
我的 python 版本是 Python 3.9.7(默认,2021 年 10 月 12 日,22:38:23)[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
lambda
定义引用列表理解的循环变量 job
(即它定义了一个闭包)。当调用 lambda 时,它将解析名称 job
,它现在指的是理解的 last 元素(即作业 B)。
相反,您可以使用默认值,以便将理解的每个对象正确绑定到相应的 lambda
函数:
threads = [threading.Thread(name=job.__str__(), target=lambda j=job: j.start()) for job in jobs]
考虑以下示例代码以获得更好的可视化效果:
>>> funcs = [lambda: print(x) for x in range(3)]
>>> for f in funcs:
... f()
...
2
2
2
>>> funcs = [lambda y=x: print(y) for x in range(3)]
>>> for f in funcs:
... f()
...
0
1
2