[英]malformed node or string on line 1 when I use ast.literal_eval using discord.py
我嘗試執行
import ast
ast.literal_eval('5+5')
然后我得到ValueError: malformed node or string on line 1: <ast.BinOp object at 0x70e6bd2830>
。
所以我嘗試了另一個:
import ast
ast.literal_eval(str(5+5))
它成功地評估了它:
10
但是當我最終在實際命令$math 5+5
上使用它時
@client.command()
async def math(ctx, expression):
resp = ast.literal_eval(str(expression))
await ctx.send(resp)
我仍然收到相同的錯誤: ValueError: malformed node or string on line 1: <ast.BinOp object at 0x7d05357700>
出於某種原因。 我正在使用 Python 3.10.5。 我該如何解決這個問題? 任何幫助,將不勝感激。
整個代碼:
import discord, ast
from discord.ext import commands
TOKEN = ""
client = commands.Bot(command_prefix="$")
prefix = client.command_prefix
def init():
client.run(TOKEN, reconnect=False)
@client.event
async def on_connect():
print('Connecting to server...')
@client.event
async def on_ready():
await client.change_presence(status=discord.Status.idle)
print('Logged in as ' + str(client.user))
print('Prefix: ' + str(prefix))
@client.command()
async def math(ctx, expression):
resp = ast.literal_eval(str(expression))
await ctx.send(resp)
init()
自 python 3.7 起,您不再允許在literal_eval
中進行加法。
我從這個答案中找到了一些可以使用的“安全表達式”。 這是一個簡單的演示:
import ast
value = input()
co = ast.parse(value, mode='eval')
for node in ast.walk(co):
if not isinstance(node, (ast.Expression, ast.Constant, ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod, ast.Pow, ast.BinOp, ast.USub, ast.UAdd, ast.UnaryOp)):
raise RuntimeError(f'Sorry! You gave an illegal syntax node: {node.__class__.__name__}')
print(eval(value))
這成功地評估了 python 中的有效數學,例如5 + 7*8 = 61
或5 ** 7 = 78125
,當然還有0.1 + 0.2 = 0.30000000000000004
。
不允許任何可能導致問題的錯誤操作,例如Call
或Name
(意思是variable_names_like_this
和function()
)。 如果您發現我遺漏了任何允許的操作,您可以簡單地將它們添加到isinstance
內的元組中以允許它們。 您可以精確地自定義允許或不允許哪些語法操作。
作為對任何想在不限制您可以使用的語法的情況下使用eval
的人的公平警告,無論您的命名空間圍欄如何,它都可以執行。 它獲取object
類,從中獲取模塊以獲取__builtins__
,然后獲取__import__
並用它做壞事。 對於更多危險,將此處的'echo hi'
替換為'rm -rf /'
:
[v for c,v in [c for c in ''.__class__.__bases__[0].__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__.items() if c == '__import__'][0]('os').system('echo hi')
根據文檔,您遇到的錯誤似乎是因為:
提供的字符串或節點只能由以下 Python 文字結構組成:字符串、字節、數字、元組、列表、字典、集合、布爾值、
None
和Ellipsis
。
所以當你這樣做時:
ast.literal_eval('5+5')
問題是+
這是一個BinOp
(對應於錯誤消息的<ast.BinOp object at 0x7d05357700>
部分)並且不能使用。
但是,當您這樣做時:
ast.literal_eval(str(5+5))
評價順序如下:
ast.literal_eval(str(5+5)) -> ast.literal_eval(str(10)) -> ast.literal_eval('10')
不再涉及+
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.