python 类中的字典函数调用



我试图在Python中实现我自己的堆栈。当我选择任何一个"pos"时,会出现错误

class Stack:
'''This is Stack Class'''
def __init__(self):
self.stack=[]
def push(self):
'''Enter item to push into stack'''
self.stack.append(raw_input("Enter item to stack: "))
def pop(self):
'''Pops item from stack'''
if len(self.stack)==0:
print 'Cannot pop from empty stack'
else:        
i = self.stack.pop(index=-1)
print ('Item popped: [%s]'%i)
def show(self):
'''Display Stack Content'''
print self.stack
choiceDict={'p':push, 'o':pop, 's':show, 'q':quit}
def menu():
'''This is a menu list for stack'''
s=Stack()
while True:
while True:
print '''Enter Choice
p) push
o) pop
s) show
q) quit'''
c=raw_input('Enter choice > ').lstrip()[0].lower()
if c not in 'posq':
print '**Invalid Choice'
else:
break
if(c=='q'):
break
s.choiceDict[c]()
if __name__=='__main__':
menu()

错误:

s.choiceDict[c]() TypeError: push() takes exactly 1 argument (0 given)

ps:如果代码中还有其他错误。我很高兴认识他们:)

顺便说一句,我只是想要解决这个问题的方法

Stack.choiceDict[c]中的函数不绑定到任何实例,无论您是否通过实例s访问类属性choiceDict。调用函数时,您仍然必须提供一个实例:

s.choiceDict[c](s)

或者更能说明问题:

Stack.choiceDict[c](s)

push属于类的每个实例。因此,您需要调度字典通过self调用属于该实例的方法。

我建议你把它放在__init__,以便在初始化一个新的类实例时定义调度程序:

def __init__(self):
self.stack = []
self.choiceDict = {'p': self.push, 'o': self.pop, 's': self.show, 'q': self.quit}

您需要将choiceDict移动到菜单函数并按如下方式初始化:

choice_dict = {'p': s.push, 'o': s.pop, 's': s.show, 'q': s.quit}

然后像这样使用它:

choice_dict[c]()

这是因为您的choiceDicts一无所知,但您的所有方法都需要self参数:

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'

使用 dict 调用foo会引发相同的错误methods因为缺少self参数。

In [20]: f.methods['foo'](f)
foo is called

或者,您可以将f传递给函数 - 这也可以工作,但似乎不太正确,因为您已经在表达式中使用了f。尽管这实际上与将choice_dict移动到我上面建议的menu函数相同。

最新更新