对于我的应用程序GUI(tkinter),我需要一个'bookkeeping'变量来保存UI小部件的当前行号。我不希望对行号进行硬编码,因为插入小部件会涉及重新编号其后的所有行号。在这种情况下,增量运算符(x++
类似于C ++)将非常方便,因为在必要时递增变量将仅需要两个附加字符。但是,Python 不支持增量运算符。
为了避免应在不同行上的元素之间的增量声明,我想出了以下解决方案,但我想知道还有什么替代方法:
rownums = list(range(100))
rowstay = lambda: rownums[0] # Return current row number and stay on row.
rowmove = lambda: rownums.pop(0) # Return current row number and move on to next.
print(f'Two items: {rowstay()}, {rowmove()}')
print(f'One item: {rowmove()}')
print(f'Two items: {rowstay()}, {rowmove()}')
例如(tkinter):
# Create some buttons.
mybutton1 = tkinter.button(master, 'Button on row 0')
mybutton2 = tkinter.button(master, 'Button on row 0')
mybutton3 = tkinter.button(master, 'Button on row 1')
# Place buttons (use mimicked increment 'operator').
mybutton1.grid(row=rowstay(), column=0)
mybutton2.grid(row=rowmove(), column=1)
mybutton3.grid(row=rowmove(), column=0)
哪些替代代码可以提供相同的功能?
从评论和答案中,我了解到使用lambda进行变异并分配lambdas不是Pythonic。一些注释建议使用,+= 1
但这正是我要避免的原因,因为每次变量应递增时都需要附加语句。具有高阶函数(或类)的解决方案++x
代替x++
。
我的解决方案(次优,请在EDIT下查看更好的解决方案):
class BookkeepingVar():
""" Variable with the ++-operator from C++ mimicked.
Example:
x = BookkeepingVar(0)
y = x() + 1 # y = 1, x = 1
z = x(1) + 1 # z = 1, x = 2
"""
def __init__(self, start=0):
self.var = [start]
def __call__(self, incr=0):
if incr:
self.var.append(self.var[0] + incr)
return self.var.pop(0)
else:
return self.var[0]
用法示例:
# Create some buttons.
mybutton1 = tkinter.button(master, 'Button on row 0')
mybutton2 = tkinter.button(master, 'Button on row 0')
mybutton3 = tkinter.button(master, 'Button on row 1')
# Place buttons.
row = BookkeepingVar(0)
mybutton1.grid(row=row(0), column=0)
mybutton2.grid(row=row(1), column=1)
mybutton3.grid(row=row(1), column=0)
请注意:
pop()
会带来问题。x++
仅更通用一点,因为它还支持除1以外的增量。__call__
实现该方法是为了使符号尽可能短。编辑:
一个没有列表的更简单,更优雅的解决方案(用法相同):
class BookkeepingVar():
""" Variable with the ++-operator from C++ mimicked.
Example:
x = BookkeepingVar(0)
y = x() + 1 # y = 1, x = 1
z = x(1) + 1 # z = 1, x = 2
"""
def __init__(self, start=0):
self.var = start
def __call__(self, incr=0):
self.var += incr
return self.var - incr
编辑2:
关于++x
vs. x++
(删除线)的评论。
鉴于您显然不使用rowspan之类的东西,我将让定制对象负责整个事情,并在
grid
内部进行调用,例如layout = Layout(); layout.row(mybutton1, mybutton2); layout.row(mybutton3)
。并且layout
可以使用正整数或来跟踪当前行itertools.count()
。显然,如果您使用的是比一堆行不起作用的更为复杂的布局。虽然您可能有更多声明性的内容。