重新定义在函数内不起作用的打印函数
Redefining print function not working within a function
我正在 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
有谁知道为什么这在函数中不起作用?
任何有关如何修复它的建议将不胜感激。
解释器不会将 print 识别为内置函数,除非您明确告诉它。不要将其声明为全局的,只需将其删除(感谢 Padraic Cunningham):本地 print 将采用您想要的定义,而全局永远不会受到影响。
您还遇到了 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))
你所需要的只是非本地并忘记你创建的所有其他变量bar 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)
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!
我正在 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
有谁知道为什么这在函数中不起作用?
任何有关如何修复它的建议将不胜感激。
解释器不会将 print 识别为内置函数,除非您明确告诉它。不要将其声明为全局的,只需将其删除(感谢 Padraic Cunningham):本地 print 将采用您想要的定义,而全局永远不会受到影响。
您还遇到了 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))
你所需要的只是非本地并忘记你创建的所有其他变量bar 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)
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!