2024-04-19 16:30:12 发布
网友
在我的python文件中,我制作了一个GUI小部件,它接受用户的一些输入。我在python文件中导入了一个python模块,它使用raw\u input()获取一些输入。我必须使用这个模块,因为它是,我没有权利改变它。当我运行python文件时,它会要求我输入(由于导入模块的原始输入)。我想在那个地方使用GUI小部件输入。 如何将用户输入(从widget获取)作为导入模块的原始输入()传递?你知道吗
首先,如果import直接将其放入脚本实际上不是一个要求(很难想象为什么会是这样),那么您可以使用subprocess或pexpect将模块(或围绕它的简单脚本)作为一个单独的进程运行。你知道吗
import
subprocess
pexpect
让我们把它变成混凝土。假设你想使用这个愚蠢的模块foo.py:
foo.py
def bar(): x = raw_input("Gimme a string") y = raw_input("Gimme another") return 'Got two strings: {}, {}'.format(x, y)
首先写一个平凡的foo.wrapper.py:
foo.wrapper.py
import foo print(foo.bar())
现在,不要在实际脚本中直接调用foo.do_thing(),而是将foo_wrapper作为子进程运行。你知道吗
foo.do_thing()
foo_wrapper
我假设您已经有了要以字符串形式发送的输入,因为这使得答案中不相关的部分变得更简单(事实上,如果您想为此使用一些GUI代码,这使得它们成为可能,除非您首先告诉我们您使用的是哪个GUI库,否则我真的无法向您演示如何进行)。你知道吗
所以:
foo_input = 'String 1\nString 2\n' with subprocess.Popen([sys.executable, 'foo_wrapper.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) as p: foo_output, _ = p.communicate(foo_input)
当然,在现实生活中,您需要为foo_wrapper.py使用适当的路径,而不是假设它在当前工作目录中,但这应该足以说明这个想法。你知道吗
foo_wrapper.py
同时,如果“我无权更改它”只是指“我没有(也不应该)签入foo项目的github站点或我们公司P4服务器上的相关子树”或其他什么,那么有一个非常简单的答案:Fork it,然后更改Fork。你知道吗
即使它有一个像LGPL这样的弱copyleft许可证:fork it,更改fork,在与原始许可证相同的许可证下发布fork,然后使用fork。你知道吗
如果您依赖于每个目标系统上安装的foo包,而不能依赖于安装替换的foo,那么问题就更大了。但是,如果实际调用raw_input的函数或方法只是foo中实际代码的一小部分,则可以在运行时通过monkeypatching foo来修复这一问题。你知道吗
raw_input
foo
这就导致了最后一种可能性:你总是可以自己使用monkeypatchraw_input。你知道吗
再一次,我假设你已经有了你需要的信息,让事情变得更简单。你知道吗
因此,首先要编写一个替换函数:
foo_input = ['String 1\n', 'String 2\n'] def fake_raw_input(prompt): global foo_input return foo_input.pop()
现在,有两种方法可以解决这个问题。通常,您要执行以下操作:
import foo foo.raw_input = fake_raw_input
这意味着foo中调用raw_input的任何代码都将看到您填充到其模块全局变量中的函数,而不是普通的内置函数。除非它做了一些非常有趣的事情(比如直接查找内置项并将其复制到局部变量或其他东西),否则这就是答案。你知道吗
如果您需要处理一个非常时髦的边缘案件,并且您不介意做一些可疑的事情,您可以这样做:
import __builtin__ __builtin__.raw_input = fake_raw_input
您必须在问题的第一个import foo之前完成此操作。另外,还不清楚这是故意保证工作,意外保证工作(应该在将来修复),还是不保证工作。但它确实有效(至少对于cpython2.5-2.7来说,这是您可能正在使用的)。你知道吗
import foo
首先,如果
import
直接将其放入脚本实际上不是一个要求(很难想象为什么会是这样),那么您可以使用subprocess
或pexpect
将模块(或围绕它的简单脚本)作为一个单独的进程运行。你知道吗让我们把它变成混凝土。假设你想使用这个愚蠢的模块
foo.py
:首先写一个平凡的
foo.wrapper.py
:现在,不要在实际脚本中直接调用
foo.do_thing()
,而是将foo_wrapper
作为子进程运行。你知道吗我假设您已经有了要以字符串形式发送的输入,因为这使得答案中不相关的部分变得更简单(事实上,如果您想为此使用一些GUI代码,这使得它们成为可能,除非您首先告诉我们您使用的是哪个GUI库,否则我真的无法向您演示如何进行)。你知道吗
所以:
当然,在现实生活中,您需要为
foo_wrapper.py
使用适当的路径,而不是假设它在当前工作目录中,但这应该足以说明这个想法。你知道吗同时,如果“我无权更改它”只是指“我没有(也不应该)签入foo项目的github站点或我们公司P4服务器上的相关子树”或其他什么,那么有一个非常简单的答案:Fork it,然后更改Fork。你知道吗
即使它有一个像LGPL这样的弱copyleft许可证:fork it,更改fork,在与原始许可证相同的许可证下发布fork,然后使用fork。你知道吗
如果您依赖于每个目标系统上安装的foo包,而不能依赖于安装替换的foo,那么问题就更大了。但是,如果实际调用
raw_input
的函数或方法只是foo
中实际代码的一小部分,则可以在运行时通过monkeypatchingfoo
来修复这一问题。你知道吗这就导致了最后一种可能性:你总是可以自己使用monkeypatch
raw_input
。你知道吗再一次,我假设你已经有了你需要的信息,让事情变得更简单。你知道吗
因此,首先要编写一个替换函数:
现在,有两种方法可以解决这个问题。通常,您要执行以下操作:
这意味着
foo
中调用raw_input
的任何代码都将看到您填充到其模块全局变量中的函数,而不是普通的内置函数。除非它做了一些非常有趣的事情(比如直接查找内置项并将其复制到局部变量或其他东西),否则这就是答案。你知道吗如果您需要处理一个非常时髦的边缘案件,并且您不介意做一些可疑的事情,您可以这样做:
您必须在问题的第一个
import foo
之前完成此操作。另外,还不清楚这是故意保证工作,意外保证工作(应该在将来修复),还是不保证工作。但它确实有效(至少对于cpython2.5-2.7来说,这是您可能正在使用的)。你知道吗相关问题 更多 >
编程相关推荐