我正在python 3.x中编写一个python脚本,我需要重新定义print
函数。当我在我的翻译中这样做时,它工作正常。但是当我使用相同的代码创建一个函数时,它会发出错误。
这是我的代码:
list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
old_print = print
def print(s):
global catstr
catstr += s
catstr = ""
for item in list:
s = item
exec(s)
print = old_print
catstr
>> 'Wow!Great!Epic!'
正如您所见,我得到了我想要的结果:'Wow!Great!Epic!'
现在我使用相同的代码创建一个函数:
def execute(list):
old_print = print
def print(s):
global catstr
catstr += s
catstr = ""
for item in list:
s = item
exec(s)
print = old_print
return catstr
现在,当我使用以下代码运行此函数时:
list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
execute(list)
我收到以下错误:
old_print = print
UnboundLocalError: local variable 'print' referenced before assignment
有谁知道为什么这不能在功能中使用?
任何有关如何修复它的建议都将受到高度赞赏。
答案 0 :(得分:2)
除非您明确说明,否则解释程序不会将打印识别为内置函数。不要将其声明为全局,只需删除它(感谢Padraic Cunningham):本地打印将采用您想要的定义,全局永远不会受到影响。
catstr 也存在转发引用问题。以下代码引出了所需的输出。
catstr = ""
def execute(list):
def print(s):
global catstr
catstr += s
for item in list:
s = item
exec(s)
print = old_print
return catstr
list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
print (execute(list))
答案 1 :(得分:2)
您只需要非本地并忘记您创建的所有其他变量吧catstr
:
def execute(lst):
def print(s):
nonlocal catstr
catstr += s
catstr = ""
for item in lst:
s = item
exec(s)
return catstr
这会给你:
In [1]: paste
def execute(lst):
def print(s):
nonlocal catstr
catstr += s
catstr = ""
for item in lst:
s = item
exec(s)
return catstr
## -- End pasted text --
In [2]: list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
In [3]: execute(lst)
Out[3]: 'Wow!Great!Epic!'
该功能中发生的任何事情都是功能的本地,因此您不必担心重置任何内容。如果您确实想要设置打印参考,可以使用old_print = __builtins__.print
。
如果您希望在不需要打印电话的情况下打印功能,请使用__builtins__.print
进行打印:
def execute(lst):
catstr = ""
def print(s):
nonlocal catstr
catstr += s
for s in lst:
exec(s)
__builtins__.print(catstr)
答案 2 :(得分:1)
你的问题已经由Prune和Padraic Cunningham回答,这是另一种实现(我猜)你想要的方式:
import io
from contextlib import redirect_stdout
g_list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
def execute(lst):
with io.StringIO() as buf, redirect_stdout(buf):
[exec(item) for item in lst]
return buf.getvalue()
def execute_modified(lst):
result = []
for item in lst:
with io.StringIO() as buf, redirect_stdout(buf):
exec(item)
result.append(buf.getvalue()[:-1])
return "".join(result)
print(execute(g_list))
print('-' * 80)
print(execute_modified(g_list))
输出:
Wow!
Great!
Epic!
--------------------------------------------------------------------------------
Wow!Great!Epic!