英文:
Python: Fix missing import with a monkey patch
问题
以下是您要翻译的内容:
我正在尝试对丢失的导入进行猴子补丁。旧的invoke() 仍然没有导入。
如果相关的话,MyClass
是一个 gdb.Command
。
(gdb) pi
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("新的调用")
... import getopt
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
>>>
(gdb) my_gdb_command
新的调用
Python 异常 <class 'NameError'>:名称 'getopt' 未定义:
Python 中发生错误:名称 'getopt' 未定义
另外,如果相关的话,初始文件和源代码看起来类似于这样:
mymodule.py:
import gdb
class MyClass(gdb.Command):
...
def invoke(self, arg, from_tty):
options, remainder = getopt.getopt(args, 'p:s:t:o:')
...
MyClass()
myothermodule.py:
import mymodule
...
导入上述内容:
(gdb) source myothermodule.py
英文:
I am trying to monkey patch a missing import. The old_invoke() still does not get the import.
In case it is relevant, MyClass
is a gdb.Command
.
(gdb) pi
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("New invoke")
... import getopt
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
>>>
(gdb) my_gdb_command
New invoke
Python Exception <class 'NameError'> name 'getopt' is not defined:
Error occurred in Python: name 'getopt' is not defined
Also, in case it is relevant, the initial files and sourcing looks something like this:
mymodule.py:
import gdb
class MyClass(gdb.Command):
...
def invoke(self, arg, from_tty):
options, remainder = getopt.getopt(args, 'p:s:t:o:')
...
MyClass()
myothermodule.py:
import mymodule
...
Sourcing the above
(gdb) source myothermodule.py
</details>
# 答案1
**得分**: 2
`old_invoke`试图引用`mymodule`的`getopt`,但该模块不存在。你需要:
```python
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("新调用")
... import getopt
...
... # 这里
... mymodule.getopt = getopt
...
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
但实际上,你应该在mymodule
中只有一个import getopt
:
# mymodule.py
import getopt
...
然后你的函数就是:
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("新调用")
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
附录
另外需要注意的是,在函数中使用import
通常不建议。除非你只调用这个函数一次(即使是那样,为什么要这样做?),每次调用函数时都会尝试加载一个模块,最好的情况下将始终对sys.modules
进行检查,而你可能不需要这样做。
将import getopt
放在脚本顶部:
import getopt
import mymodule
mymodule.getopt = getopt
这就是你可能希望它在脚本中的位置。
英文:
old_invoke
is trying to reference mymodule
's getopt
, which doesn't exist. You need:
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("New invoke")
... import getopt
...
... # here
... mymodule.getopt = getopt
...
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
But, realistically, you should just have an import getopt
in mymodule
:
# mymodule.py
import getopt
...
Then your function is simply:
>>> import mymodule
>>> old_invoke = mymodule.MyClass.invoke
>>> def new_invoke(self, *k, **kw):
... print("New invoke")
... old_invoke(self, *k, **kw)
...
>>> mymodule.MyClass.invoke = new_invoke
Addendum
As another note, using import
in a function isn't generally recommended. Unless you are only calling this function once (and even then, why?), every time you call the function you are attempting to load a module, which at best will always do a check against sys.modules
when you probably don't have to.
Have the import getopt
at the top of the script:
import getopt
import mymodule
mymodule.getopt = getopt
Which is where you'd probably expect this to be anyways
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论