eval() 不接受关键字参数

问题描述 投票:0回答:2

代码:

import tkinter as tk

win = tk.Tk()

text = tk.Text(win, width = 50, height = 20, bg = 'black', fg = 'lightgreen', wrap = tk.WORD)
text.pack()

text.tag_configure('prompt', foreground = 'magenta')
text.tag_configure('output', foreground = 'yellow')

text.insert('end', '>>> ', 'prompt')

def on_return(*args):
  cmd = text.get('prompt.last', 'end')
  if cmd:
     try:
       output = str(eval(cmd, globals = {"__builtins__":None}))
     except Exception as e:
       output = str(e)
  text.insert('end', '\n' + output, 'output')
  text.insert('end', '\n>>> ' + output, 'prompt')
  return 'break'

text.bind('<Return>', on_return)

win.mainloop()

为了获得此输出:eval() 不接受关键字参数,只需在文本小部件上键入任何内容,然后按 Enter 键。

我应该怎么做才能避免这种输出?

python tkinter eval
2个回答
2
投票

在代码中,您需要从字典中传递的参数中删除“globals =”。正确的行是:

output = str(eval(cmd, {"__builtins__":None}))

0
投票

默认情况下,当您声明函数时,可以通过名称或关键字传递参数。但是,可以声明一个函数以禁止位置或关键字传递。许多内置函数(例如

eval
range
)都使用它来减少调用时间,允许库所有者自由重命名参数,并禁止奇怪的调用顺序。 请参阅 PEP 570 了解更多信息。

要调用这些函数,您必须以正确的顺序给出参数。如果您只想提供

eval
局部变量,而不是全局变量,只需传递
global
的默认值:
eval(expression, None, your_locals)
.

您可以通过在参数列表中添加正斜杠

/
和星号
*
来声明这样的函数。斜杠之前的参数仅是位置参数,斜杠和星号之间的参数是关键字或位置参数,星号之后的参数仅是关键字。

例如,要获得类似于 eval 的行为,您可以声明:

def eval2(expression, globals=None, locals=None, /):
    pass

eval2
仅接受位置参数。如果你用关键字调用它,你会得到一个异常:

eval2('print("hello", location)', locals={'location':'world'})
...
TypeError: eval2() got some positional-only arguments passed as keyword arguments: 'locals'

您还可以声明一个混合使用仅位置参数、普通参数和仅关键字参数的函数:

def example_function(positional1, positional2, /, keyword_or_positional1, keyword_or_positional2, *, keyword1, keyword2):
    pass

顺便说一句,这也是您在 Python 帮助实用程序中的某些签名中看到斜杠的原因:

help(hasattr)
...
hasattr(obj, name, /)

因为 obj 和 name 位于斜杠之前,所以它们不能作为关键字参数传递。由于某种原因,除非有普通参数以及仅位置参数,否则 HTML 文档中不包含斜杠。

© www.soinside.com 2019 - 2024. All rights reserved.