我试图在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]()
这是因为您的choiceDict
对s
一无所知,但您的所有方法都需要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
函数相同。