gpt4 book ai didi

python - IronPython - 有没有办法从数据库加载 python 脚本或从字符串资源嵌入?

转载 作者:行者123 更新时间:2023-11-28 18:33:10 25 4
gpt4 key购买 nike

当 IronPython 尝试解析/加载它找不到的模块时,有没有办法从 IronPython 中捕获某种 even?

我们想将模块存储在数据库中或将它们嵌入到 DLL 中并通过调用 import mymodule 导入它们。我们根本不想涉及文件系统。当我们说 import something 时,我们不希望它在\Lib 或任何文件系统中查找。

以下代码可以很好地加载嵌入在 DLL 中的 Python 代码块。它仅在没有导入时有效。

    var myScript = new StreamReader(Assembly.GetAssembly(this.GetType()).GetManifestResourceStream("Resource.Name.To.My.Script")).ReadToEnd()
var engine = IronPython.Hosting.Python.CreateEngine();
var scope = engine.CreateScope();
var result = engine.Execute(myScript, scope);

和 python 代码:

print('hello world')

如果有导入,则无法正常工作。它不知道如何解析模块的位置。

我能让它工作的唯一方法是确保我们需要的任何模块都对文件系统中的引擎可见。这涉及使用 engine.GetSearchPaths()(查看它正在寻找的路径)和使用 engine.SetSearchPaths() 附加任何其他搜索路径。但这些来自文件系统,这不是我想要的。

我想一个不错的方法可能是从引擎接收某种事件,例如“OnLookingForModuleNamedXYZ(moduleName)”。然后我可以在数据库或 DLL 的嵌入式资源中查找模块并发回模块的字符串。

我该怎么做?

最佳答案

您需要添加自定义导入 Hook 。 Python 添加了一种注册自定义导入 Hook 的方法。在此机制之前,您必须覆盖内置的 __import__ 函数。但它特别容易出错,尤其是当多个库都试图添加自定义导入行为时。

PEP 0302详细描述了该机制。

本质上,您需要创建两个对象——一个 Finder 对象和一个 Loader 对象。

Finder 对象应该定义一个名为find_module 的函数

This method will be called with the fully qualified name of the module. If the finder is installed on sys.meta_path , it will receive a second argument, which is None for a top-level module, or package.__path__ for submodules or subpackages [5] . It should return a loader object if the module was found, or None if it wasn't.

如果find_module函数找到模块并返回一个Loader对象,Loader对象应该定义一个load_module函数

This method returns the loaded module or raises an exception, preferably ImportError if an existing exception is not being propagated. If load_module() is asked to load a module that it cannot, ImportError is to be raised.

这是一个详细说明其工作原理的简短示例:

import sys
import imp

class CustomImportFinder(object):

@staticmethod
def find_module(fullname, path=None):
# Do your custom stuff here, look in database, etc.
code_from_database = "VAR = 1"
return CustomImportLoader(fullname, path, code_from_database)


class CustomImportLoader(object):

def __init__(self, fullname, path, code_from_database):
super(CustomImportLoader, self).__init__()
self.fullname = fullname
self.path = path
self.code_from_database = code_from_database

def is_package(fullname):
# is this a package?
return False

def load_module(self, fullname):
code = self.code_from_database
ispkg = self.is_package(fullname)
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<%s>" % self.__class__.__name__
mod.__loader__ = self
if ispkg:
mod.__path__ = []
mod.__package__ = fullname
else:
mod.__package__ = fullname.rpartition('.')[0]
exec(code, mod.__dict__)
return mod

sys.meta_path.append(CustomImportFinder)

import blah
print(blah)
# <module 'blah' (built-in)>
print(blah.VAR)
# 1

关于python - IronPython - 有没有办法从数据库加载 python 脚本或从字符串资源嵌入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35005521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com