代码没有将“checks”变量传递给函数

2024-10-02 00:43:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一个名为checks的变量列表传递给函数installFunc,由于某些原因,它似乎不起作用,下面是我(认为是)的相关代码:

def installFunc(checks):
    subprocess.call("md c:\MGInstall", shell=True)
    subprocess.call (u"net use w: \\it01\files")
    if checks[0] == 1:
        subprocess.call(u"w:\\software\\snagitup.exe")
    if checks[1] == 1:
        subprocess.call(u"w:\\software\\camtasia.exe")
    if checks[2] == 1:
        urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\gotomeeting.exe")
        subprocess.call (u"c:\\MGinstall\\gotomeeting.exe")
    if checks[3] == 1:
        sixtyfourcheck()
        if is64bit == True:
            urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\tortoiseSVN.exe")
        elif is64bit == False:
            urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\tortoiseSVN.exe")
    #urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\MGinstall.exe")
    #subprocess.call (u"c:\\MGinstall\\MGinstall.exe")
    #subprocess.call (u"w:\\printers\\installer\\printer.exe")

app = Tk()

w = Label(app, text="IT Automatic Installer")
w.pack()

text = ["Snagit", "Camtasia", "GotoMeeting", "TortoiseSVN"]
variables = []
for name in text:
    variables.append(IntVar())
    Checkbutton(text=name, variable=variables[-1]).pack()

checks = [variable.get() for variable in variables]
b = Button(text="Install", command= lambda : installFunc(checks))
b.pack()

app.mainloop()

现在,我尝试了一些不同的方法-实际上是由stack overflow提供的lamba部分-我在理解它的工作原理时遇到了一些困难。你知道吗

但我遇到的最大问题是-为什么没有将检查传递给installFunc()?我想将检查的完整列表(输入的项目数)传递给installFunc()。你知道吗


Tags: textappifvariablesurllibcallvariableexe
3条回答

variable.get()返回IntVar实例在被调用时的值,该值甚至在应用程序启动之前。所以,它将充满零。你知道吗

def installCommand(variables):
    checks = [variable.get() for variable in variables]
    return installFunc(checks)

b = Button(text="Install", command= lambda v=variables: installCommand(v))
b.pack()

此外,还需要将variables作为默认参数传递给lambda,这样就不会与全局和局部变量发生冲突。你知道吗

你至少可以用几种方法来做。就我个人而言,我会将安装程序抽象为一个对象,正如Hugh Bothwell的评论所提到的那样。这具有最大的灵活性以及对状态的简洁包容。但是,如果您只使用一个函数,那么可以使用functools来“curry”函数:动态创建一个嵌入给定参数的新函数。以下是您需要做的更改。。。你知道吗

def installFunc(checks):
    subprocess.call("md c:\MGInstall", shell=True)
    subprocess.call (u"net use w: \\it01\files")
    if checks[0].get( ) == 1:
        subprocess.call(u"w:\\software\\snagitup.exe")
    if checks[1].get( ) == 1:
        subprocess.call(u"w:\\software\\camtasia.exe")
    if checks[2].get( ) == 1:
        urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\gotomeeting.exe")
        subprocess.call (u"c:\\MGinstall\\gotomeeting.exe")
    if checks[3].get( ) == 1:
        sixtyfourcheck()
        if is64bit == True:
            urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\tortoiseSVN.exe")
        elif is64bit == False:
            urllib.urlretrieve(u"LONGURL", u"c:\\MGinstall\\tortoiseSVN.exe")


import functools

app = Tk()

w = Label(app, text="IT Automatic Installer")
w.pack()

text = ["Snagit", "Camtasia", "GotoMeeting", "TortoiseSVN"]
variables = []
for name in text:
    variables.append(IntVar())
    Checkbutton(text=name, variable=variables[-1]).pack()

checks = [variable.get() for variable in variables]

#  Here's where we "curry" the installFunc, producing the new doInstall function.
doInstall = functools.partial(installFunc, checks)

b = Button(text="Install", command = doInstall)
b.pack()

app.mainloop()

问题是变量.get()创建一个不可变的int,并且您的列表“checks”永远不会更改。你可能真正想要的是。。。你知道吗

import functools

app = Tk()

w = Label(app, text="IT Automatic Installer")
w.pack()

text = ["Snagit", "Camtasia", "GotoMeeting", "TortoiseSVN"]
variables = []
for name in text:
    variables.append(IntVar())
    Checkbutton(text=name, variable=variables[-1]).pack()

checks = [variable for variable in variables]

#  Here's where we "curry" the installFunc, producing the new doInstall function.
doInstall = functools.partial(installFunc, checks)

b = Button(text="Install", command = doInstall)
b.pack()

app.mainloop()

根据我之前的评论,重构版本:

import urllib
import subprocess
import os
import Tkinter as tk

class ProgramInstaller(object):
    def __init__(self, name, descr, do_install):
        self.name    = name
        self.descr   = descr
        self.do_install = do_install    # can be function or list of strings

    def install(self):
        if callable(self.do_install):
            self.do_install()
        else:
            for s in self.do_install:
                subprocess.call(s)

TEMP_DIR = r"c:\MGInstall"

def makeTempDir(dir=TEMP_DIR):
    # need to expand on this - what if dir already exists, etc
    os.mkdir(dir)

def removeTempDir(dir=TEMP_DIR):
    # need to expand on this - del files in dir before rmdir, etc
    os.rmdir(dir)

def installGoToMeeting():
    makeTempDir()
    url = "http://www.gotomeeting.com/download/something"
    fname = os.path.join(TEMP_DIR, "gotomeeting.exe")
    urllib.urlretrieve(url, fname)
    subprocess.call(fname)
    removeTempDir()

def installTortoiseSVN():
    makeTempDir()
    if is64bit(): url = "http://www.tortoisesvn.net/download/something/64bit"
    else:         url = "http://www.tortoisesvn.net/download/something/32bit"
    fname = os.join(TEMP_DIR, "tortoisesvn.exe")
    urllib.urlretrieve(url, fname)
    subprocess.call(fname)
    removeTempDir()

installers = (
    ProgramInstaller("SnagIt",      "Take screen-shots",           [r"net use w: \\it01\files", r"w:\software\snagitup.exe"]),
    ProgramInstaller("Camtasia",    "Record your desktop",         [r"net use w: \\it01\files", r"w:\software\camtasia.exe"]),
    ProgramInstaller("GoToMeeting", "Web conferencing",            installGoToMeeting),
    ProgramInstaller("TortoiseSVN", "(Sub)Version control client", installTortoiseSVN),
    ProgramInstaller("Printer",     "HP4020 Printer drivers",      [r"net use w: \\it01\files", r"w:\printers\installer\printer.exe"])
)

def doInstall():        # install-button callback
    for inst in installers:
        if inst.cbvar.get():
            inst.install()

def main():
    app = tk.Tk()
    tk.Label(app, text="IT Automatic Installer").pack()

    # need to fiddle with a grid layout to make this look right
    for inst in installers:
        inst.cbvar = tk.IntVar()
        tk.Checkbutton(text=inst.name, variable=inst.cbvar).pack()
        tk.Label(text=inst.descr).pack()

    tk.Button(text="Install", command=doInstall()).pack()
    app.mainloop()

if __name__=="__main__":
    main()

相关问题 更多 >

    热门问题