【问题标题】:Creating objects whose names are stored in the configuration file创建名称存储在配置文件中的对象
【发布时间】:2019-09-09 23:29:36
【问题描述】:

我正在尝试创建一个程序,该程序将根据配置文件中注册的处理程序创建对象,以将它们传递给另一个类的方法。

我有一个配置文件,其中包含一组应传递给我的应用程序方法的某些处理程序的名称。 这是 config.json 文件:

{
    "handlers": [
        "handler1",
        "handler2"
    ]
}

如何选择存储在配置中的必要对象?

下面的代码显示,要注册对象,您需要将它们保存在一个列表中。 解决此问题的最佳做法是什么?

class Observer:
    #some code

class BaseHandler:
    #some code

class Handler1(BaseHandler):
    #some code

class Handler2(BaseHandler):
    #some code

class Handler3(BaseHandler):
    #some code

handler1 = Handler1()
handler2 = Handler2()
handler3 = Handler3()
handlers = [handler1, handler2, handler3]

observer = Observer()
observer.method_for_handling(handlers)

【问题讨论】:

  • 什么建立映射是 json 文件字符串和类名?即"handler1"Handler1。什么时候进行对象注册,什么时候读取/使用json文件?

标签: python json config


【解决方案1】:

假设您有文件 main.py

class Observer:
  def __init__(self, handlers):
    self.handlers = handlers

  def event(self):
    for handler in self.handlers:
      handler.event()

class BaseHandler:
  pass

class Handler1(BaseHandler):
  def event(self):
    print("Handler1")

class Handler2(BaseHandler):
  def event(self):
    print("Handler2")

class Handler3(BaseHandler):
  def event(self):
    print("Handler3")

现在您的config.json 文件具有有效 名称,并且它是有效的 JSON。

{"handlers": ["Handler1", "Handler2"]}

然后要加载它,您可以执行以下操作: configure.py

import observers
import json

with open("config.json", "r") as fp:
  config = json.loads(fp.read())

handlers = [getattr(observers, handler_name)() for handler_name in config['handlers']]
# At this point handlers are ready to be used so u can write any custom logic u want.
ob = observers.Observer(handlers)
ob.event()

结果:

Handler1
Handler2

【讨论】:

    【解决方案2】:

    您可以使用globals()locals(),具体取决于您需要什么以及您想要什么以及将JSON 转换为有效的python 字典,如下例所示:

    import json
    
    
    my_json = '''{
        "handlers": [
            "Handler1",
            "Handler2"
        ]
    }'''
    
    
    class Observer:
        def method_for_handling(self, handlers):
            for handler in handlers:
                try:
                    globals()[handler]()
                except KeyError:
                    print('Handler not supported! : ', handler)
    
    
    class BaseHandler:
        def event(self):
            print('Base Handler')
    
    
    class Handler1(BaseHandler):
        def __init__(self):
            print('Init in handler 1')
    
        def event(self):
            print('Base Handler1')
    
    
    class Handler2(BaseHandler):
        def __init__(self):
            print('Init in handler 2')
    
        def event(self):
            print('Base Handler2')
    
    
    conf = json.loads(my_json)
    observer = Observer()
    observer.method_for_handling(conf['handlers'])
    

    输出:

    Init in handler 1
    Init in handler 2
    

    您可以进一步推动这个示例,您可以通过在 JSON 属性中添加方法来直接访问这些方法。这是一个例子:

    # See here how we defined the first handler
    my_json = '''{
        "handlers": [
            "Handler1.event",
            "Handler2"
        ]
    }'''
    
    class Observer:
        def method_for_handling(self, handlers):
            for handler in handlers:
                try:
                    if '.' in handler:
                        # Here i'm assuming that we'll use only one method
                        # of the handler class. You can improve it to use
                        # chained methods if you want
                        _handler, *_, func = handler.partition('.')
                        main = globals()[_handler]()
                        getattr(main, func)()
                    else:
                        globals()[handler]()
                except KeyError:
                    print('Handler not supported! : ', handler)
    

    因此,如果您修改实际的 method_for_handling,您将得到一个输出:

    Init in handler 1
    Base Handler1
    Init in handler 2
    

    所以,在这里我们可以看到,BaseHandler1 类的方法 event 都被执行了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 2018-12-10
      • 2017-05-03
      • 2016-07-13
      • 2014-09-14
      • 2011-04-14
      • 1970-01-01
      相关资源
      最近更新 更多