Python 需要 1 个位置参数,但给出了 2 个

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37791744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 19:56:19  来源:igfitidea点击:

takes 1 positional argument but 2 were given

pythonpython-3.xtkintersubprocesspopen

提问by MrChaosBude

I would like to run a command line tool to run in a separate function and passed to the button click the additional command for this program but each time I get this as a response.

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

takes 1 positional argument but 2 were given

需要 1 个位置参数,但给出了 2 个

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

the error

错误

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

can some body help me

身体能帮帮我吗

there is something wrong with **args

**args 有问题

采纳答案by Tom Myddeltyn

It is because you are providing it a positional argument here:

这是因为您在此处为其提供了位置参数:

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

command want's a callback function. and you are passing it the response from the adbmethod. (see here fore more: http://effbot.org/tkinterbook/button.htm)

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

when that line is being called, self.adb("devices")is being called. if you look at your definition of adb

当那条线路被调用时,self.adb("devices")正在被调用。如果你看看你的定义adb

def adb(self, **args):

You are only asking for 1 positional argument selfand any number of keyword arguments **argsthen you are calling it self.adb("devices")with 2 positional arguments of selfand "devices"

你只需要 1 个位置参数self和任意数量的关键字参数,**args然后你self.adb("devices")用 2 个位置参数self"devices"

What you will need to do is have an intermediate method, if you want to have the adbmethod more general, or just put "devices"into the adbmethod.

你将需要做的是有一个中间的方法,如果你想拥有的adb方法更一般的,或者只是把"devices"adb法。

edit

编辑

See also here: http://effbot.org/zone/tkinter-callbacks.htmSee the section "Passing Argument to Callbacks"

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

edit 2: code example

编辑2:代码示例

If you do this, it should work:

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

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

and then change your function to a single *inlieu of a **(keyword arg expansion) See here: https://stackoverflow.com/a/36908/6030424for more explanation.

然后将您的函数更改*为 a **(关键字 arg 扩展)的单个inlieu,请参见此处:https: //stackoverflow.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)

回答by Hai Vu

The problem is in the way you declare args: it should be *args(one asterisk) instead of **args(two asterisks). One asterisk specifies any number of positional arguments, where as two asterisks means any number of named arguments.

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

Also, you need to pass argscorrect to adb.exe:

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

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