I have been working on a dialer button class since yesterday. It makes sense to use the command design pattern here, and I want to separate the commands and the buttons so I can change the functionality of every button at runtime.
So we are talking about something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13class DialerButtons:
def __init__(self):
self.command_table = [
self.numpad_1, self.numpad_2, self.numpad_3,
self.numpad_4, self.numpad_5, self.numpad_6,
self.numpad_7, self.numpad_8, self.numpad_9,
self.cancel, self.numpad_0, self.dial]
def numpad_0(self):
self.text.append('0')
def execute(self, n):
self.command_table[n]()
and you can use this class like this:
1
2
3dialer = DialerButtons()
dialer.execute(0)
dialer.execute(8)1
2
3
4
5
6
def _numpad_commands_factory(cls):
for n in xrange(0, 10):
setattr(cls, 'numpad_%d' % n, lambda self: self.text.append(str(n)))
DialerButtons._numpad_commands_factory()
The reason is that the context of numpad_0, for example, is actually “f(self): self.text.append(str(n)))” instead of “f(self): self.text.append(‘0’)”. so, what it does here is that it refers to the variable n inside _numpad_commands_factory, and the value of n is 9 after you executed it.
The correct code piece is:
1
2
3
4
5
6
def _numpad_commands_factory(cls):
def f(chr):
return lambda self: self.text.append(chr)
for n in xrange(0, 10):
setattr(cls, 'numpad_%d' % n, f(str(n)))