我试图绕过从模块导入,所以在__init__.py
我可以注入这样的代码:
globals().update(
{
"foo": lambda: print("Hello stackoverflow!")
}
)
所以,如果我import mymodule
,我可以致电mymodule.foo
。这是一个简单的概念,对此无用,因为您实际上只能定义foo
。
所以,我的想法是修改globals
模块字典,所以如果它找不到函数foo
它会去任何地方,我可以注入代码,为此我试过:< / p>
from importer import load #a load function to search for the code
from functools import wraps
def global_get_wrapper(f):
@wraps(f)
def wrapper(*args):
module_name, default = args
res = f(*args)
if res is None:
return load(module_name)
return res
return wrapper
globals().get = global_get_wrapper(globals().get) # trying to substitute get method
但它给了我一个错误:
AttributeError: 'dict' object attribute 'get' is read-only
我的另一个想法是将可用的函数,类等名称预加载到模块字典中,然后懒洋洋地加载它们。
我没有想法来实现这一目标,我也不知道这是否可行。 我应该去写我自己的python导入器吗?还是有其他我无法思考的可能性? 提前谢谢。
答案 0 :(得分:7)
不是黑客攻击globals()
,最好为您的模块定义__getattr__
,如下所示:
foo = 'foo'
def bar():
return 'bar'
import sys
import module_name
class MyModule(object):
def foobar(self):
return 'foobar'
def __getattr__(self, item):
return getattr(module_name, item)
sys.modules[__name__] = MyModule()
然后:
>>> import my_module
>>> my_module.foo
'foo'
>>> my_module.bar()
'bar'
>>> my_module.foobar()
'foobar'
答案 1 :(得分:3)
PEP 562为模块引入了__getattr__
。在理论基础上,它还描述了以前的Python版本的变通方法。
有时可以方便地定制或以其他方式控制对模块属性的访问。一个典型的例子是管理弃用警告。典型的解决方法是将模块对象的
__class__
分配给types.ModuleType
的自定义子类,或者使用自定义包装器实例替换sys.modules
项。通过识别直接在模块中定义的__getattr__
来简化此过程将会很方便,该模块将像普通的__getattr__
方法一样,除了它将在模块实例上定义。
所以您的mymodule
可能如下:
foo = 'bar'
def __getattr__(name):
print('load you custom module and return it')
以下是它的表现:
>>> import mymodule
>>> mymodule.foo
'bar'
>>> mymodule.baz
load you custom module and return it
答案 2 :(得分:0)
我不太明白。这对你有用吗?
try:
mymodule.foo()
except:
print("whatever you wanted to do")