Вам необходимо переместить choiceDict
в функцию меню и инициализировать следующим образом:
choice_dict = {'p': s.push, 'o': s.pop, 's': s.show, 'q': s.quit}
Затем используйте его следующим образом:
choice_dict[c]()
Это потому, что ваш choiceDict
ничего не знает о s
, но все ваши методы требуют self
param:
In [14]: class Foo:
...: def foo(self):
...: print('foo is called')
...: methods = {'foo': foo}
...:
In [15]: f = Foo()
In [16]: f.foo()
foo is called
In [17]: f.foo
Out[17]: <bound method Foo.foo of <__main__.Foo object at 0x111ec2048>>
In [18]: f.methods['foo']
Out[18]: <function __main__.Foo.foo>
Здесь вы можете увидеть разницу между f.methods['foo']
и f.foo
.Первый связан с f
, второй - просто функция внутри класса
In [19]: f.methods['foo']()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-a6f2f6e3b450> in <module>()
----> 1 f.methods['foo']()
TypeError: foo() missing 1 required positional argument: 'self'
Вызов foo
с использованием methods
dict вызывает ту же ошибку, поскольку пропущен параметр self
.
In [20]: f.methods['foo'](f)
foo is called
В качестве альтернативы, вы можете передать f
функции - это также будет работать, но, кажется, не совсем правильно, потому что вы уже используете f
в выражении.Хотя по сути это то же самое, что перейти choice_dict
к функции menu
, как я предлагал выше.