我已经尝试了多种方法来挑选具有依赖关系的python函数,遵循StackOverflow上的许多建议(例如dill,cloudpickle等),但似乎都遇到了一个我无法弄清楚的基本问题.
我有一个主模块,试图从导入的模块中挑选一个函数,通过ssh发送它以进行unickled并在远程机器上执行.
所以主要有:
import dill (for example)
import modulea
serial=dill.dumps( modulea.func )
send (serial)
Run Code Online (Sandbox Code Playgroud)
在远程机器上:
import dill
receive serial
funcremote = dill.loads( serial )
funcremote()
Run Code Online (Sandbox Code Playgroud)
如果被腌制和发送的函数是main本身定义的顶级函数,那么一切正常.当它们位于导入的模块中时,加载功能将失败,并显示"未找到模块模块"类型的消息.
模块名称似乎与函数名称一起被腌制.我没有看到任何方法来"修复"pickle以消除依赖关系,或者在接收器中创建一个虚拟模块以成为unpickling的接收者.
任何指针都将非常感激.
--prasanna
我试图使用基于PEP302的导入钩子来捕获模块的导入,所以我可以有一些加密的.py文件,这些文件将在运行时加载.我在https://github.com/citrusbyte/python-obfuscation上关注python模糊处理的模板.
基本思路很简单:使用插入到sys.meta_path中的Finder()函数拦截import命令,该函数捕获一个import指令.Finder检查模块是否是我们想要自己处理的模块,如果是,则返回自定义Loader对象.否则它会忽略导入.自定义加载程序在sys.modules中创建一个条目,并读入python模块源并使用PEP302文档中定义的exec将其添加到新创建的模块中.
这很好用,但我有一个我无法弄清楚的具体情况.假设3个文件,main,foo和bar.main设置导入钩然后导入foo和bar.foo本身进口吧.所以情况是:
main:
set_import_hook
import foo
import bar
foo:
import bar
bar:
<irrelevant>
Run Code Online (Sandbox Code Playgroud)
我在Finder函数中将调试语句设置为钩子,以查看它的传递内容.
当我有未加密的代码(即我不处理的代码并自己添加到sys.modules时,打印输出显示以下行为:
Finder (foo)
Finder (bar) called from inside foo when foo itself is loaded
Finder (bar) called from main after returning from the import foo
Run Code Online (Sandbox Code Playgroud)
当我自己处理和加载foo和bar文件时,这是行为:
Finder (foo)
Finder (foo.bar) tries to load bar in the context of foo
Finder (bar) called from main after returning from import foo
Run Code Online (Sandbox Code Playgroud)
这会导致sys.modules中存在两个bar版本.如果你在两种情况下查看sys.modules.keys(),在第一种情况下它只显示foo和bar.在第二种情况下,它显示foo,foo.bar和bar.
我不明白这种行为.创建模块的过程如PEP 302文档中所述.这是我使用的:
module = sys.modules.setdefault(name, imp.new_module(name))
module.__file__ = filename
module.__path__ = [os.path.dirname(os.path.abspath(file.name))]
module.__loader__ …Run Code Online (Sandbox Code Playgroud)