你能告诉我我的代码是否有更优雅的解决方案,我需要什么?
我的小程序从最多七个输入字段输入文本输入(确切的数字可以是 由用户指定)。然后将输入字符串与散布的固定连接起来 文本元素。生成一个字符串形式的单个输出。
该程序完美无缺。然而,我的编程让我觉得非常不优雅和非pythonic。你能帮助我改进,促进我的学习吗?
两点:
1)我想总结所有七个文本输入的字符串长度。我明白地加了他们, 这不优雅。我怎么能以更好的方式做到这一点?
string_length = len(str(E1.get())) + len(str(E2.get())) + len(str(E3.get())) + len(str(E4.get())) + len(str(E5.get())) + len(str(E6.get())) + len(str(E7.get()))
2) 根据用户使用Tkinter Scale S 指定的输入字段数,可以启用或禁用输入字段( En )以进行输入。
然后将从这些Entry字段派生的Strings str(En.get())连接起来 其间的固定字符串元素 partM 会产生字符串 m 。 (整个字符串的两侧也是partL和partR。)我通过查询变量来完成此操作 通过get()方法的比例 S (输入字段数)。 然后该程序决定如何通过if / elif进行?
设置的比例越高,添加的文本元素越多。然而,这是一个非常相似的任务,因为可能会有一个更直接的解决方案。
这会产生很长的代码行,并且不适合扩展程序以获取更多的Entry字段。我怎么能做得更好?
代码摘录:
if S.get() == 1:
if string_length == 22*S.get():
m = partL + str(E1.get()) + partR
do_something()
else:
warning()
elif S.get() == 2:
if string_length == 22*S.get():
m = partL + str(E1.get()) + partM + str(E2.get()) + partR
do_something()
else:
warning()
elif S.get() == 3:
if string_length == 22*S.get():
m = partL + str(E1.get()) + partM + str(E2.get()) + partM + str(E3.get()) + partR
do_something()
else:
warning()
我是Python的新手。我也是编程新手。然而,我很自豪我写了一些工作正常的代码,并为我和其他人做了一些有用的事情。 我欢迎任何建议。
答案 0 :(得分:6)
如果您的字段是E1到E7,并且每个字段都有get
方法,则应该为您提供它们的总长度:
fields = [E1, E2, E3, E4, E5, E6, E7]
total_length = sum(len(str(f.get())) for f in fields)
如果您只想要收集的值,这就足够了:
fields = [E1, E2, E3, E4, E5, E6, E7]
values = [f.get() for f in fields]
答案 1 :(得分:1)
我会尝试回答问题的第二部分,因为@ g.d.d.c已经对第一部分有了很好的答案。
为避免代码重复,您应该查看现有代码中的常见部分。
if string_length == 22*S.get():
...
else:
warning()
出现在所有三种情况中。因此,您可以将其提取为:
if string_length != 22*S.get():
warning()
else:
if S.get() == 1:
...
elif S.get() == 2:
...
elif S.get() == 3:
...
do_something()
如果您预见到支持更多案例,可以使用功能图扩展
functions = {1 : one,
2 : two,
3 : three
}
def one():
m = partL + str(E1.get()) + partR
def two():
m = partL + str(E1.get()) + partM + str(E2.get()) + partR
def three():
m = partL + str(E1.get()) + partM + str(E2.get()) + partM + str(E3.get())
你打电话给:
functions[S.get()]()
答案 2 :(得分:1)
无论if string_length == 22*S.get()
的值如何,S.get()
检查都会发生,如果失败,则始终会发出警告。为了简化代码并减少代码重复,您可以将该检查移到基于S.get()
的值切换的逻辑之外:
if string_length != 22*S.get():
warning()
else:
if S.get() == 1:
...
elif S.get() == 2:
...
...
如果您创建字段列表而不是使用7个编号变量,则可以轻松地使用切片和索引以可伸缩的方式选择所需的字段,而不需要为每个数字分别设置子句。此外,join
字符串方法允许您使用指定的分隔符将多个字符串连接在一起:
if string_length != 22*S.get():
warning()
else:
middle = partM.join(str(field.get()) for field in fields[:S.get()])
m = partL + middle + partR
do_something()
让我们分解partM.join(str(field.get()) for field in fields[:S.get()])
:
fields
应该是您创建的字段列表,而不是使用7个变量。
fields[:S.get()]
正在切片表示法。它列出了S.get()
的第一个fields
元素。 (如果fields
没有足够的元素,则切片会返回整个列表的副本。)
str(field.get()) for field in fields[:S.get()]
是一个生成器表达式。它创建一个遍历fields[:S.get()]
的迭代器,并调用列表中每个字段的get()
方法。这会导致第一个S.get()
字段的字符串上的迭代器。 (生成器表达式必须始终出现在括号中。如果生成器表达式是函数的唯一参数,则函数调用括号将填充此角色。否则,必须在括号周围加上括号。)
partM.join(str(field.get()) for field in fields[:S.get()])
从该迭代器获取所有字符串并将它们粘在一起,在每对字符串之间用partM
分隔。
答案 3 :(得分:0)
这是一种连接字符串以使用.join(在此处插入内容)方法的方法。这基本上是函数.append(在这里插入一些东西)的字符串。