英文:
Load a class dynamically
问题
以下是翻译好的部分,不包括代码:
我有一个在启动时动态添加模块的软件。
启动发生在我的Python程序启动之后,所以我无法使用普通的“import DynModule”导入模块,而必须在运行时进行此操作。
因此,我想要做类似于以下的事情:
def load_module():
try:
import site
site.addsitedir(r"C:\Users\...")
from DynModule import Foo
except (ModuleNotFoundError, ImportError) as e:
logger.error("无法导入动态模块")
class AccessClass(Process):
def __init__(self):
Process.__init__(self)
logger.info("占位符类实例")
def do_something(self):
logger.info("占位符执行某些操作")
else:
class AccessClass(Process):
def __init__(self):
Process.__init__(self)
logger.info("正确的类实例,用于动态加载的模块")
def do_something(self):
logger.info("实际执行某些操作")
然后在主程序中执行以下操作:
def action_on_load(self):
from loader import load_module, AccessClass
load_module()
self._access = AccessClass()
self._access.do_something() # 输出 "实际执行某些操作"
然而,由于AccessClass是在try-except子句内部定义的,因此我无法导入它。我该如何继续并使其正常工作?
英文:
I have a software that dynamically adds modules at startup.
The start happens after the start of my Python program, so I cannot import the modules with a normal "import DynModule", but have to do this during runtime.
Therefore I would like to do something like this:
def load_module():
try:
import site
site.addsitedir(r"C:\Users\...")
from DynModule import Foo
except (ModuleNotFoundError, ImportError) as e:
logger.error("Could not import the dynamic module")
class AccessClass(Process):
def __init__(self):
Process.__init__(self)
logger.info("Placeholder class instance")
def do_something(self):
logger.info("Placeholder does something")
else:
class AccessClass(Process):
def __init__(self):
Process.__init__(self)
logger.info("The right class instance to use the dynamically loaded module")
def do_something(self):
logger.info("Actually does something")
And then do something like this in the main program:
def action_on_load(self):
from loader import load_module, AccessClass
load_module()
self._access = AccessClass()
self._access.do_something() # prints "Actually does something"
However, I cannot import AccessClass as it is defined inside the try-except clause.
How can I proceed and get this to work?
答案1
得分: 1
以下是您要翻译的内容:
问题不在于它在try
语句中定义,而在于它在函数中定义,其中名称AccessClass
是一个局部变量。您可以将名称声明为全局变量:
def load_module():
global AccessClass
...
因为class
语句就像是一个复杂的赋值语句:它定义了一个类,然后将其绑定到一个名称上。不过,请注意,该类直到您实际调用函数时才会分配给该名称。在您的主程序中,您需要编写类似于以下内容:
def action_on_load(self):
import loader # 还没有AccessClass
loader.load_module() # 现在loader.AccessClass已定义。
self._access = loader.AccessClass()
self._access.do_something() # 输出“实际执行某些操作”
或者,您可以简单地返回该类:
def load_module():
...
return AccessClass
def action_on_load(self):
from loader import load_module
AccessClass = load_module()
self._access = AccessClass()
self._access.do_something() # 输出“实际执行某些操作”
注意:代码部分不需要翻译。
英文:
The problem isn't that its defined in the try
statement, but that it's defined in the function, where the name AccessClass
is a local variable. You can declare the name as global:
def load_module():
global AccessClass
...
because a class
statement is like a fancy assignment statement: it defines a class, then binds it to a name. Note, though, that the class won't be assigned to the name until you actually call the function. In your main program, you'd need to write something like
def action_on_load(self):
import loader # No AccessClass yet
loader.load_module() # Now loader.AccessClass is defined.
self._access = loader.AccessClass()
self._access.do_something() # prints "Actually does something"
Or, you can simply return the class:
def load_module():
...
return AccessClass
def action_on_load(self):
from loader import load_module
AccessClass = load_module()
self._access = AccessClass()
self._access.do_something() # prints "Actually does something"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论