【问题标题】:python threading app error to many argumentspython线程应用程序错误到许多参数
【发布时间】:2012-12-18 12:13:28
【问题描述】:

这个python源代码有什么问题?

import threading
import subprocess as sub

def ben(fil):
    pr = sub.Popen(fil,stdout=sub.PIPE,stderr=sub.PIPE)
    output, errors = pr.communicate()
    print output

theapp = '''blender
            blender-softwaregl'''.split()
print theapp

for u in theapp:
    print u
    tr = threading.Thread(target=ben, args=(u))
    tr.daemon = True
    tr.start()

错误是:

['blender', 'blender-softwaregl']
blender
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/local/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
TypeError: ben() takes exactly 1 argument (7 given)

blender-softwaregl
Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/local/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
TypeError: ben() takes exactly 1 argument (18 given)

这是我的问题。这是什么错误?

 TypeError: ben() takes exactly 1 argument (18 given)

【问题讨论】:

    标签: python multithreading python-2.7


    【解决方案1】:

    threading.Threadargs 参数需要一个序列,但您提供的是一个字符串。这导致它将字符串的每个字母解释为单独的参数,从而导致目标函数的参数过多。

    您已经非常接近拥有正确的代码了。您只需要通过在括号中添加尾随逗号来修复您的元组语法:

    tr = threading.Thread(target=ben, args=(u,)) # comma makes args into a 1-tuple
    

    【讨论】:

    • 您可以将其包装在列表中 Thread(target=ben, args=[u]) 作为替代方案。虽然元组在语义上更有效,但可能更容易阅读。
    • 如果我使用 args=[u] 不工作,如果我使用 args=(u,) 接缝工作但是:文件“/usr/local/lib/python2.7/subprocess.py ",第 1237 行,在 _execute_child : 'NoneType' object has no attribute 'close' 所以需要关闭线程吗?你能帮我吗?
    【解决方案2】:

    由于某种原因,您似乎将字符列表作为参数而不是字符串传递。

    我明白了,因为搅拌机有 7 个字母,而您收到了类型错误 7 个参数传递。 Blender-softwaregl 有 18 个字母,所以你有 18 个参数的类型错误,而不是一个。

    如果您想向子进程传递多个参数。 Popen,尝试使用变量名填充和值列表传递字典。

    def ben(fil):
        pr = sub.Popen(fil,stdout=sub.PIPE,stderr=sub.PIPE)
        output, errors = pr.communicate()
        print output
    
    d = {'fil':['command1', 'command2']}
    
    ben(**d)
    

    还有一件事。开子进程为什么还要开线程???子进程是一个独立的进程,不需要线程部分。我猜你的代码可以在没有线程部分的情况下工作。

    【讨论】:

    • 我不明白。你能提供更多信息吗?你告诉我 d 和 **d[args] 。问题是什么 ?为什么我只发送一个参数时是 18 个参数?我有点迷失了。谢谢你。问候。
    • d 是一个保存字典的变量,当您输入 **d['args'] 时,这意味着您将字典作为参数传递,仅此而已...但我发现了您的问题! Blender 有 7 个字母 blender-softwaregl haz 18 个字母 我猜你以某种方式传递了一个字符列表作为参数:)
    • 我很快就添加了我的答案,所以我会修复它。无论如何,我正在查看您的代码,但我注意到了一件事......
    • 你根本不需要线程,只需将 tr = threading.Thread(target=ben, args=(u)) tr.daemon = True tr.start() 替换为 ben(fil)跨度>
    • 我想用 time 命令来看看这个二进制文件是如何快速打开的。这就是使用线程的原因。 args=(u,) 是解决方案。
    猜你喜欢
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    相关资源
    最近更新 更多