Pythonic Logic - 寻求一种更有效的方法来处理检查 0 和 1 列表的多个 if 语句
Pythonic Logic - Seeking a more efficient approach to multiple if statements that check a list of 0's and 1's
我一直在 Python 中开发一个简单的 GUI 来从 PowerBi 中提取数据,它看起来类似于下图:
该应用运行良好,但我希望提高它的效率。
checkbar 使用以下代码生成:
Datasets = [
'Option 1', 'Option 2', 'Option 3',
'Option 4', 'Option 5',
'Option 6', 'Option 7',
'Option 8', 'Option 9']
print(os.getcwd())
cwd = os.getcwd
class Checkbar(Frame):
def __init__(self, parent=None, picks=[], side=LEFT, anchor=W):
Frame.__init__(self, parent)
self.vars = []
for pick in picks:
var = IntVar()
chk = Checkbutton(self, text=pick, variable=var, width=22, anchor='w')
chk.pack(side=side, anchor=anchor, expand=YES)
self.vars.append(var)
def state(self):
return map((lambda var: var.get()), self.vars)
if __name__ == '__main__':
root = Tk()
root.title("PowerBI Data Collector")
root.iconphoto(True, PhotoImage(
file="Icon/Directory"))
responseLabel = Label(root)
# Check
data1 = Checkbar(root, Datasets[0:3], anchor=W)
data2 = Checkbar(root, Datasets[3:6], anchor=W)
data3 = Checkbar(root, Datasets[6:9], anchor=W)
data1.grid(row = 3, column = 1, padx = 1, pady = 1)
data1.config(relief=GROOVE, bd=1)
data2.grid(row = 4, column = 1, padx = 1, pady = 1)
data2.config(relief=GROOVE, bd=1)
data3.grid(row = 5, column = 1, padx = 1, pady = 1)
data3.config(relief=GROOVE, bd=1)
根据用户在复选框中的选择,生成一个 0 和 1 的列表来描述输入的状态,使用代码:
dataState = list(data1.state())
dataState.extend(list(data2.state()))
dataState.extend(list(data3.state()))
因此,如果选择选项 2 和选项 4,dataState 将显示为:[0,1,0,1,0,0,0,0,0]
从这里开始,有许多 if
语句检查列表中它们各自的整数是否为 1,如果是,则调用各自的函数从 PowerBi 中提取特定于该复选框的数据。下面详细介绍了其中的一些:
if dataState == [0]*len(Datasets): # nothing
responseLabel.destroy()
responseLabel = Label(text = "Please select from the checklist above")
responseLabel.grid(row = 7, column = 1)
if dataState[0] == 1: # option2
# Response Label
responseLabel.destroy()
try:
uf.option2(User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option 1 data download failed")
responseLabel.grid(row = 7, column = 1)
if dataState[1] == 1: # option1
# Response Label
responseLabel.destroy()
try:
uf.option1(User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option 2 data download failed")
responseLabel.grid(row = 7, column = 1)
这个效率很低,以前只有3个选项还好,现在有9个,希望能增加更多。我正在考虑将 if
语句部分转换为 for
循环,并且对应于列表中的 1 的循环迭代称为特定函数,但这似乎也很低效,所以我提出了在这里提问,希望能找到更好的建议。
谢谢!
我在 option1 和 option2 的 if 下看到的代码之间的唯一区别是被调用的函数:uf.option1 与 uf.option2 以及失败打印。这种代码重复是可以避免的。
首先,使用字典将选项与其在uf中的功能进行映射:
option_funcs={1: uf.option1, 2: uf.option2 ...}
然后将“if”中的代码转换为一个函数,该函数获取一个整数选项作为参数并调用相关的 uf.option
def download_data(option):
responseLabel.destroy()
try:
option_funcs[option](User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option {} data download failed".format(option))
responseLabel.grid(row = 7, column = 1)
最后,将所有 if 替换为遍历 dataState 的 for:
for count, value in enumerate(dataState, start=1):
if value: download_data(count)
一个简单的、可扩展的选项是将每个选项的代码变成一个函数并将它们放入 list
或 tuple
,例如:
optionFunc = (opt1, opt2, opt3, etc.)
然后您可以遍历 dataState
并调用关联的函数,例如:
for index, state in enumerate(dataState):
if state:
option_func[index](responseLabel)
可能有更复杂的方法来做到这一点,也许您使用的 GUI 代码可以将标签与您可以用作字典索引的复选框相关联,但这是一般的想法。
(我将 optionFunc
放在 camelCase
中以与您的其余代码保持一致,但在 Python 中 snake_case
将是首选形式)
我一直在 Python 中开发一个简单的 GUI 来从 PowerBi 中提取数据,它看起来类似于下图:
该应用运行良好,但我希望提高它的效率。
checkbar 使用以下代码生成:
Datasets = [
'Option 1', 'Option 2', 'Option 3',
'Option 4', 'Option 5',
'Option 6', 'Option 7',
'Option 8', 'Option 9']
print(os.getcwd())
cwd = os.getcwd
class Checkbar(Frame):
def __init__(self, parent=None, picks=[], side=LEFT, anchor=W):
Frame.__init__(self, parent)
self.vars = []
for pick in picks:
var = IntVar()
chk = Checkbutton(self, text=pick, variable=var, width=22, anchor='w')
chk.pack(side=side, anchor=anchor, expand=YES)
self.vars.append(var)
def state(self):
return map((lambda var: var.get()), self.vars)
if __name__ == '__main__':
root = Tk()
root.title("PowerBI Data Collector")
root.iconphoto(True, PhotoImage(
file="Icon/Directory"))
responseLabel = Label(root)
# Check
data1 = Checkbar(root, Datasets[0:3], anchor=W)
data2 = Checkbar(root, Datasets[3:6], anchor=W)
data3 = Checkbar(root, Datasets[6:9], anchor=W)
data1.grid(row = 3, column = 1, padx = 1, pady = 1)
data1.config(relief=GROOVE, bd=1)
data2.grid(row = 4, column = 1, padx = 1, pady = 1)
data2.config(relief=GROOVE, bd=1)
data3.grid(row = 5, column = 1, padx = 1, pady = 1)
data3.config(relief=GROOVE, bd=1)
根据用户在复选框中的选择,生成一个 0 和 1 的列表来描述输入的状态,使用代码:
dataState = list(data1.state())
dataState.extend(list(data2.state()))
dataState.extend(list(data3.state()))
因此,如果选择选项 2 和选项 4,dataState 将显示为:[0,1,0,1,0,0,0,0,0]
从这里开始,有许多 if
语句检查列表中它们各自的整数是否为 1,如果是,则调用各自的函数从 PowerBi 中提取特定于该复选框的数据。下面详细介绍了其中的一些:
if dataState == [0]*len(Datasets): # nothing
responseLabel.destroy()
responseLabel = Label(text = "Please select from the checklist above")
responseLabel.grid(row = 7, column = 1)
if dataState[0] == 1: # option2
# Response Label
responseLabel.destroy()
try:
uf.option2(User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option 1 data download failed")
responseLabel.grid(row = 7, column = 1)
if dataState[1] == 1: # option1
# Response Label
responseLabel.destroy()
try:
uf.option1(User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option 2 data download failed")
responseLabel.grid(row = 7, column = 1)
这个效率很低,以前只有3个选项还好,现在有9个,希望能增加更多。我正在考虑将 if
语句部分转换为 for
循环,并且对应于列表中的 1 的循环迭代称为特定函数,但这似乎也很低效,所以我提出了在这里提问,希望能找到更好的建议。
谢谢!
我在 option1 和 option2 的 if 下看到的代码之间的唯一区别是被调用的函数:uf.option1 与 uf.option2 以及失败打印。这种代码重复是可以避免的。
首先,使用字典将选项与其在uf中的功能进行映射:
option_funcs={1: uf.option1, 2: uf.option2 ...}
然后将“if”中的代码转换为一个函数,该函数获取一个整数选项作为参数并调用相关的 uf.option
def download_data(option):
responseLabel.destroy()
try:
option_funcs[option](User=userDetails[0], Pass = userDetails[1])
responseLabel = Label(text = "All data downloaded")
responseLabel.grid(row = 7, column = 1)
except:
responseLabel = Label(text = "option {} data download failed".format(option))
responseLabel.grid(row = 7, column = 1)
最后,将所有 if 替换为遍历 dataState 的 for:
for count, value in enumerate(dataState, start=1):
if value: download_data(count)
一个简单的、可扩展的选项是将每个选项的代码变成一个函数并将它们放入 list
或 tuple
,例如:
optionFunc = (opt1, opt2, opt3, etc.)
然后您可以遍历 dataState
并调用关联的函数,例如:
for index, state in enumerate(dataState):
if state:
option_func[index](responseLabel)
可能有更复杂的方法来做到这一点,也许您使用的 GUI 代码可以将标签与您可以用作字典索引的复选框相关联,但这是一般的想法。
(我将 optionFunc
放在 camelCase
中以与您的其余代码保持一致,但在 Python 中 snake_case
将是首选形式)