动态加载一个类

huangapple go评论93阅读模式
英文:

Load a class dynamically

问题

以下是翻译好的部分,不包括代码:

我有一个在启动时动态添加模块的软件。
启动发生在我的Python程序启动之后,所以我无法使用普通的“import DynModule”导入模块,而必须在运行时进行此操作。

因此,我想要做类似于以下的事情:

  1. def load_module():
  2. try:
  3. import site
  4. site.addsitedir(r"C:\Users\...")
  5. from DynModule import Foo
  6. except (ModuleNotFoundError, ImportError) as e:
  7. logger.error("无法导入动态模块")
  8. class AccessClass(Process):
  9. def __init__(self):
  10. Process.__init__(self)
  11. logger.info("占位符类实例")
  12. def do_something(self):
  13. logger.info("占位符执行某些操作")
  14. else:
  15. class AccessClass(Process):
  16. def __init__(self):
  17. Process.__init__(self)
  18. logger.info("正确的类实例,用于动态加载的模块")
  19. def do_something(self):
  20. logger.info("实际执行某些操作")

然后在主程序中执行以下操作:

  1. def action_on_load(self):
  2. from loader import load_module, AccessClass
  3. load_module()
  4. self._access = AccessClass()
  5. 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:

  1. def load_module():
  2. try:
  3. import site
  4. site.addsitedir(r"C:\Users\...")
  5. from DynModule import Foo
  6. except (ModuleNotFoundError, ImportError) as e:
  7. logger.error("Could not import the dynamic module")
  8. class AccessClass(Process):
  9. def __init__(self):
  10. Process.__init__(self)
  11. logger.info("Placeholder class instance")
  12. def do_something(self):
  13. logger.info("Placeholder does something")
  14. else:
  15. class AccessClass(Process):
  16. def __init__(self):
  17. Process.__init__(self)
  18. logger.info("The right class instance to use the dynamically loaded module")
  19. def do_something(self):
  20. logger.info("Actually does something")

And then do something like this in the main program:

  1. def action_on_load(self):
  2. from loader import load_module, AccessClass
  3. load_module()
  4. self._access = AccessClass()
  5. 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是一个局部变量。您可以将名称声明为全局变量:

  1. def load_module():
  2. global AccessClass
  3. ...

因为class语句就像是一个复杂的赋值语句:它定义了一个类,然后将其绑定到一个名称上。不过,请注意,该类直到您实际调用函数时才会分配给该名称。在您的主程序中,您需要编写类似于以下内容:

  1. def action_on_load(self):
  2. import loader # 还没有AccessClass
  3. loader.load_module() # 现在loader.AccessClass已定义。
  4. self._access = loader.AccessClass()
  5. self._access.do_something() # 输出“实际执行某些操作”

或者,您可以简单地返回该类:

  1. def load_module():
  2. ...
  3. return AccessClass
  4. def action_on_load(self):
  5. from loader import load_module
  6. AccessClass = load_module()
  7. self._access = AccessClass()
  8. 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:

  1. def load_module():
  2. global AccessClass
  3. ...

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

  1. def action_on_load(self):
  2. import loader # No AccessClass yet
  3. loader.load_module() # Now loader.AccessClass is defined.
  4. self._access = loader.AccessClass()
  5. self._access.do_something() # prints "Actually does something"

Or, you can simply return the class:

  1. def load_module():
  2. ...
  3. return AccessClass
  4. def action_on_load(self):
  5. from loader import load_module
  6. AccessClass = load_module()
  7. self._access = AccessClass()
  8. self._access.do_something() # prints "Actually does something"

huangapple
  • 本文由 发表于 2023年2月14日 01:24:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定