接受 1 个位置参数,但给出了 2 个

Posted

技术标签:

【中文标题】接受 1 个位置参数,但给出了 2 个【英文标题】:takes 1 positional argument but 2 were given 【发布时间】:2016-10-13 23:45:02 【问题描述】:

我想运行一个命令行工具以在单独的函数中运行并传递给按钮,单击该程序的附加命令,但每次我都得到这个作为响应。

from tkinter import *
import subprocess


class StdoutRedirector(object):
    def __init__(self,text_widget):
        self.text_space = text_widget

    def write(self,string):
        self.text_space.insert('end', string)
        self.text_space.see('end')

class CoreGUI(object):
    def __init__(self,parent):
        self.parent = parent
        self.InitUI()

        button = Button(self.parent, text="Check Device", command= self.adb("devices"))
        button.grid(column=0, row=0, columnspan=1)

    def InitUI(self):
        self.text_box = Text(self.parent, wrap='word', height = 6, width=50)
        self.text_box.grid(column=0, row=10, columnspan = 2, sticky='NSWE', padx=5, pady=5)
        sys.stdout = StdoutRedirector(self.text_box)

    def adb(self, **args):
        process = subprocess.Popen(['adb.exe', args], stdout=subprocess.PIPE, shell=True)
        print(process.communicate())
        #return x.communicate(stdout)


root = Tk()
gui = CoreGUI(root)
root.mainloop()

错误

Traceback (most recent call last):
  File "C:/Users/Maik/PycharmProjects/Lernen/subprocessExtra.py", line 33, in <module>
    gui = CoreGUI(root)
  File "C:/Users/Maik/PycharmProjects/Lernen/subprocessExtra.py", line 18, in __init__
    button = Button(self.parent, text="Check Device", command= self.adb("devices"))
TypeError: adb() takes 1 positional argument but 2 were given
Exception ignored in: <__main__.StdoutRedirector object at 0x013531B0>
AttributeError: 'StdoutRedirector' object has no attribute 'flush'

Process finished with exit code 1

可以帮帮我吗

**args 有问题

【问题讨论】:

我们能看到确切的错误,以及它发生的具体行 ´Traceback(最近一次调用最后):文件“*/subprocessExtra.py”,第 33 行,在 gui = CoreGUI(root) 文件“*/subprocessExtra.py”,第 18 行,在 init button = Button(self.parent, text="Check Device", command= self.adb("devices"))忽略在:<__main__.stdoutredirector object at> AttributeError: 'StdoutRedirector' object has no attribute 'flush' Process finished with exit code 1 ' 这应该是问题:^) 看起来使用重定向器的代码需要 flush 方法,但您没有提供。您是否尝试将 flush 方法添加到重定向器?您还错误地使用了command 属性。见***.com/q/5767228/7432 我尝试通过代码 sn-ps 来理解,并在他们学习如何编码时尝试。 lambda 不起作用 【参考方案1】:

这是因为你在这里提供了一个位置参数:

button = Button(self.parent, text="Check Device", command= self.adb("devices"))

命令需要一个回调函数。并且您将 adb 方法的响应传递给它。 (更多信息请参见此处:http://effbot.org/tkinterbook/button.htm)

当该行被调用时,self.adb("devices") 被调用。 如果你看看你对adb的定义

def adb(self, **args):

您只要求 1 个位置参数 self 和任意数量的关键字参数 **args 然后您将其称为 self.adb("devices") 并带有 2 个位置参数 self"devices"

你需要做的是有一个中间方法,如果你想让adb方法更通用,或者只是将"devices"放入adb方法中。

编辑

参见此处:http://effbot.org/zone/tkinter-callbacks.htm参见“将参数传递给回调”部分

编辑 2:代码示例

如果你这样做,它应该可以工作:

button = Button(self.parent, text="Check Device", command=lambda:  self.adb("devices"))

然后将您的函数更改为单个 * 代替 **(关键字 arg 扩展)请参阅此处:https://***.com/a/36908/6030424 了解更多说明。

def adb(self, *args):
    process = subprocess.Popen(['adb.exe', args], stdout=subprocess.PIPE, shell=True)
    print(process.communicate())
    #return x.communicate(stdout)

【讨论】:

我想使用未固定的设备,因为我想使用相同的定义来创建其他更多的 agumente 如果我添加 button = Button(self.parent, text="Check Device", command=lambda: self.adb(self, "devises")) 错误说 button = Button(self.parent, text="Check Device", command=lambda: self.adb(self, "devises")) TypeError: adb() takes 2 positional arguments but 3 were given Exception ignored in: &lt;__main__.StdoutRedirector object at 0x01193230&gt; AttributeError: 'StdoutRedirector' object has no attribute 'flush'【参考方案2】:

问题在于您声明args 的方式:它应该是*args(一个星号)而不是**args(两个星号)。一个星号指定任意数量的位置参数,其中两个星号表示任意数量的命名参数。

另外,您需要将args 正确传递给adb.exe

def adb(self, *args):
    process = subprocess.Popen(['adb.exe'] + args, stdout=subprocess.PIPE, shell=True)

【讨论】:

以上是关于接受 1 个位置参数,但给出了 2 个的主要内容,如果未能解决你的问题,请参考以下文章

TypeError: login() 接受 1 个位置参数,但给出了 2 个

TypeError: __init__() 接受 1 个位置参数,但给出了 2 个

Python:函数接受 1 个位置参数,但给出了 2 个,如何?

TypeError: done() 接受 1 个位置参数,但给出了 2 个

to_date() 接受 1 个位置参数,但给出了 2 个

PyTorch - TypeError: forward() 接受 1 个位置参数,但给出了 2 个