在我的python文件中,我创建了一个GUI小部件,它从用户那里获得了一些输入。我在我的python文件中导入了一个python模块,它使用raw_input()获取一些输入。我必须按原样使用此模块,我无权更改它。当我运行我的python文件时,它询问输入(由于导入模块的raw_input())。我想在那个地方使用GUI小部件输入。 如何将用户输入(我们从小部件中获取)作为导入模块的raw_input()传递?
答案 0 :(得分:1)
首先,如果将{{1}直接放入你的脚本实际上不是一个要求(并且很难想象为什么会这样),你可以运行模块(或一个简单的脚本)作为单独的流程,使用import
或subprocess
。
让我们具体化。假设你想使用这个愚蠢的模块pexpect
:
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
现在,不要直接在真实脚本中调用import foo
print(foo.bar())
,而是将foo.do_thing()
作为子进程运行。
我将假设你已经有了想要用字符串发送它的输入,因为这使得答案中不相关的部分更简单(事实上,它使它们成为可能 - 如果你想使用一些GUI代码,除非你先告诉我们你正在使用哪个GUI库,否则我真的无法告诉你如何。
所以:
foo_wrapper
当然,在现实生活中,你需要为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项目的github网站或我们公司的P4服务器上的相关子树的登记权”或者其他,有一个非常简单的答案:分叉它,然后换叉子。
即使它有像LGPL这样弱的copyleft许可证:fork它,更改fork,在与原始版本相同的许可证下发布你的fork,然后使用你的fork。
如果您依赖于每个目标系统上安装的foo软件包,并且不能依赖于您安装的替换foo,那就更有问题了。但是,如果实际调用foo_wrapper.py
的函数或方法只是raw_input
中实际代码的一小部分,则可以在运行时通过monkeypatching foo
来解决这个问题。
这导致了最后的可能性:你总是可以monkeypatch foo
本身。
同样,我将假设您已经拥有了所需的输入,以使事情更简单。
所以,首先你要写一个替换函数:
raw_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
之前执行此操作。此外,目前尚不清楚这是否有意保证工作,意外保证工作(并应在未来修复),或不保证工作。但它确实有效(至少对于CPython 2.5-2.7,你可能正在使用它)。