简体   繁体   English

如何在不调用文件的情况下运行全局代码

[英]How do I run global code without calling the file

I'm writing a python application that allows users to write their own plugins and extend the core functionality I provide - 我正在编写一个python应用程序,允许用户编写自己的插件并扩展我提供的核心功能 -

$ tree project_dir/
.
├── application.py
├── plugins
│   ├── __init__.py
│   ├── example_plugin.py
│   ├── plugin1.py
│   ├── plugin2.py
│   └── plugin3
│       ├── sounds
│       │   └── test.wav
│       └── player.py
└── plugins_manager.py

plugins_manager.py - plugins_manager.py -

class Manager(object):

    def __init__(self):
        self.plugins = {}

    def register_plugin(self, name, plugin_func):
        self.plugins[name] = plugin_func

application.py initializes Manager instance globally - application.py全局初始化Manager实例 -

manager = Manager()

def main():
    print manager.plugins

main()

Each plugin is required to import the Manager instance from application.py and register itself like, plugin1.py - 每个插件都需要从application.py导入Manager实例并注册自己,如plugin1.py -

from application import manager

PLUGIN_NAME = "AAC_Player"

def plugin_function(options):
    # do something

manager.register_plugin(PLUGIN_NAME, plugin_function)

Now when I run application.py, obviously nothing gets printed. 现在,当我运行application.py时,显然没有任何内容被打印出来。 How do I make the plugins register themselves (call .register_plugin() ) at program startup? 如何在程序启动时自己注册插件(调用.register_plugin() )?

So on that lines, a more generalised question would be - How can I make python execute a line of code that's global in a file without actually running the file? 所以在这一行上,一个更普遍的问题是 - 如何让python执行一行代码,这些代码在文件中是全局的而不实际运行文件?

Suggestions on improving the plugin architecture welcome! 关于改进插件架构的建议欢迎!

You can use the __import__() builtin to import the plugins, and then include the register_plugin() call in either the plugin file example_plugin.py or in __init__.py if it's a directory. 您可以使用__import__()内置来导入插件,然后在插件文件example_plugin.py__init__.py . __import__()如果它是目录register_plugin()包含register_plugin()调用。

For example, let's say this is your project structure: 例如,假设这是您的项目结构:

./
application.py
plugins_manager.py
plugins/
    __init__.py
    plugin1.py
    plugin2.py
    plugin3/
        __init__.py

Plugins have these contents: 插件包含以下内容:

$ cat plugins/plugin1.py
print 'Plugin 1'

$ cat plugins/plugin2.py
print 'Plugin 2'

$ cat plugins/plugin3/__init__.py
print 'Plugin 3'

In plugins_manager.py , identify the plugins and import them in: plugins_manager.py ,标识插件并将其导入:

from os import listdir
from os.path import exists, isdir, basename, join, splitext

def is_plugin(filename):
  filepath = join('plugins', filename)
  _, ext = splitext(filepath)

  # Ignore plugins/__init__.py
  if filename == '__init__.py':
    return False

  # Find single file plugins
  if ext == '.py':
    return True

  # Find plugins packaged in directories
  if isdir(filepath) and exists(join(filepath, '__init__.py')):
    return True

  return False

plugin_names = [ splitext(p)[0] for p in listdir('plugins/') if is_plugin(p) ]
plugins = [ __import__('plugins.' + p) for p in plugin_names ]

Should get output similar to: 应该得到类似于的输出:

Plugin 1
Plugin 2
Plugin 3

Note that in this case the plugins variable contains a list of the module objects imported. 请注意,在这种情况下, plugins变量包含导入的模块对象的列表。

Strictly speaking I'd say there is no way to run code without it being invoked somehow. 严格来说,我会说如果不以某种方式调用代码就无法运行代码。 To do this, the running program can use 为此,正在运行的程序可以使用

import importlib

so that once you've found the file you can import it with: 这样,一旦找到该文件,您可以将其导入:

mod = importlib.import_module(import_name, pkg_name)

and if that file provides a known function (Run in this case) you can call it with: 如果该文件提供已知函数(在这种情况下运行),您可以使用以下命令调用它:

mod.Run(your_args)

This works for Python 2.7. 这适用于Python 2.7。 Version 3 might be different. 版本3可能不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用全局变量的情况下运行此代码? - How can I run this code without using global variables? 如何在子进程中运行 function 和 arguments 而不直接调用它? - How do I run a function with arguments in a subprocess without calling it directly? 如何修改和运行 my.py 文件中的一大段代码,而不必每次都读取整个.xlsx 文件? - How do I modify and run a chunk of code from my .py file without having to read the whole .xlsx file every time? 如何编写没有全局变量的代码? - How do I write this without global variables? 我如何运行没有路径的python文件? - How do I run python file without path? 如何在不使用全局函数的情况下在代码中引用局部变量 - How do I reference local variables across my code without using the global functions 如何在不使用全局变量的情况下重构我的工作? - How do I refactor my work without using global variables? 如何在不使用全局变量的情况下完成同一件事? - How do I accomplish the same thing without using a global variable? 如何在没有 global 关键字的情况下全球化函数中的变量? - How do I globalize a variable in a function without the global keyword? 如何在没有操作系统的情况下运行 python - How do I run python without an OS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM