gpt4 book ai didi

python - 当我需要返回值时,exec 返回一个非类型

转载 作者:行者123 更新时间:2023-12-01 03:12:03 29 4
gpt4 key购买 nike

我之前问了一个问题,但遇到了第二个问题。

我正在编写一个程序,该程序读取文本文件并执行该文件中的所有代码。这是针对类的,我们必须使用 exec()

我在运行代码时遇到此错误,无数次搜索都没有找到解决方案。

Traceback (most recent call last):
File "doxecute.py", line 28, in <module>
replace_code(statements, contents)
File "doxecute.py", line 17, in replace_code
contents = contents.replace("{%" + statement + "%}", statement)
TypeError: Can't convert 'NoneType' object to str implicitly

代码是

import sys
import re



def sortecute(data):
funcs = re.findall(r'{%(.*?)%}',data,re.DOTALL)#find executable statements
return funcs

def replace_code(statements, contents):
for statement in statements:
if not statement[5:].startswith("print("):
exec(statement[5:]) #execute code after the (letter)
contents = contents.replace("{%" + statement + "%}", "")
else:
statement = exec(statement[5:])#error is here
contents = contents.replace("{%" + statement + "%}", statement)

print(contents)

f = open(sys.argv[1],"r")
contents = f.read()
f.close()

statements = sortecute(contents) #get data from file
statements = sorted(statements) #sorts by letter

replace_code(statements, contents)

这是我读入的文件。

The number {% (c) print(x) %} is a random number between 1 and 6
inclusive. If we multiply it by 2, we get {% (d) print(2*x) %}.

What's interesting is that the statements may appear out of order in the
document. {% (a) import random %} Thus I might generate the random
number in a location in the document well after referencing it.
{% (b) x = random.randint(1,6) %}

我不知道如何获取 exec 语句的值。有人可以向我解释如何按照下面列出的方式正确使用它

You will need to use the exec function in Python. To get the output back, you will need to redirect output to your own stream. Your program should accept a filename as a command-line argument to operate on [8]

最佳答案

exec将始终返回 None 。来自 documentation :

exec(object[, globals[, locals]])

This function supports dynamic execution of Python code. object must be either a string or a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error occurs). [1] If it is a code object, it is simply executed. In all cases, the code that’s executed is expected to be valid as file input (see the section “File input” in the Reference Manual). Be aware that the return and yield statements may not be used outside of function definitions even within the context of code passed to the exec() function. The return value is None.

这是一个相当奇怪的请求。但是您可以像这样捕获输出:

>>> s = """The number {% (c) print(x) %} is a random number between 1 and 6
... inclusive. If we multiply it by 2, we get {% (d) print(2*x) %}.
...
... What's interesting is that the statements may appear out of order in the
... document. {% (a) import random %} Thus I might generate the random
... number in a location in the document well after referencing it.
... {% (b) x = random.randint(1,6) %}"""
>>> import re
>>> stmts = re.findall(r'{%\s*\((\w*)\)\s*(.*)%}',s)
>>> stmts
[('c', 'print(x) '), ('d', 'print(2*x) '), ('a', 'import random '), ('b', 'x = random.randint(1,6) ')]

现在,您必须将输出重定向到稍后可以操作的某个流:

>>> import io
>>> import sys
>>> stream = io.StringIO()
>>> stdout = sys.stdout # this keeps stdout so we can set it back
>>> sys.stdout = stream
>>> for _, statement in sorted(stmts):
... exec(statement)
...
>>> sys.stdout = stdout # remember to reset stdout!

现在,您可以获得打印的值:

>>> stream.getvalue()
'5\n10\n'
>>> stream.getvalue().split()
['5', '10']

尽管如此,我认为更简单的方法是将 namespace 传递给字典:

>>> namespace = {}
>>> for _, statement in sorted(stmts):
... exec(statement, namespace)
...
5
10
>>> namespace.keys()
dict_keys(['__builtins__', 'random', 'x'])

命名空间将加载正常的 __builtins__除非你自己提供一份。因此,要获取在执行的代码中创建的每个名称,您可以找到namspace.keys之间的区别。 dictview以及包含字符串 "__builtins__" 的集合

>>> namespace.keys()
dict_keys(['__builtins__', 'random', 'x'])
>>> vals = namespace.keys() - {'__builtins__'}
>>> vals
{'random', 'x'}
>>> for val in vals:
... print(namespace[val])
...
<module 'random' from '/Users/juan/anaconda3/lib/python3.5/random.py'>
5
>>>

不过,如果您使用的是 python 3.4 >= 将 stdout 重定向到某个流会容易得多:

>>> import contextlib
>>> stream = io.StringIO()
>>> with contextlib.redirect_stdout(stream):
... for _, statement in stmts:
... exec(statement)
...
>>> stream.getvalue()
'5\n10\n'
>>> stream.getvalue().split()
['5', '10']

关于python - 当我需要返回值时,exec 返回一个非类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42802071/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com