繁体   English   中英

python static on call magic方法

[英]python static on call magic method

我正在尝试建立一个包含Registry实例的Service类。 RegistryService类如下:

class Registry:

    def __init__(self, registrar):
        self.registrar = registrar

    def get(self, key):
        layers = key.split('.')
        value = self.registrar
        for item in layers:
            value = value[item]
        return value

class Service:

    instance = None

    @classmethod
    def boot(cls, object, configuration = {}):
        if cls.instance is None:
            cls.instance = object(configuration)

我目前想要的是在调用boot函数之后,应该可以从Service类静态访问注册表函数,而无需在Service类中定义函数。 因此,在使用以下代码启动后,我想使用get函数。

Service.boot(Config, {'a' : 'b'});
Service.get('a');

注意:配置对象是注册表的扩展

我已经尝试过__getattr__魔术方法,但它不适用于静态方法。 我试过__call__但是之后我需要调用Service().get() ,这不是我想要的。

那么,是否有可能在python中做到这一点? 我不想在Service层中重新定义类方法。

注意:在PHP中,存在__callStatic()函数,该函数正是我想要的。 但是,我找不到在python上的实现。

如果您可以稍微修改一下通话方式,我可以想象这是可行的:

cfg = Service.boot(Config, {'a' : 'b'})
cfg.get('a')

这样,如果使boot()返回提供这些方法的对象,则可以使其与__getattr__完美配合。

如果没有,您可以尝试以下方法之一:

  1. 只需调用cfg.instance.get('a')
  2. Service一个元类:

     class Registry: def __init__(self, registrar): self.registrar = registrar def get(self, key): layers = key.split('.') value = self.registrar for item in layers: value = value[item] return value class DeflectToInstance(type): def __getattr__(selfcls, a): # selfcls in order to make clear it is a class object (as we are a metaclass) try: # first, inquiry the class itself return super(Meta, selfcls).__getattr__(a) except AttributeError: # Not found, so try to inquiry the instance attribute: return getattr(selfcls.instance, a) class Service: __metaclass__ = DeflectToInstance instance = None @classmethod def boot(cls, NewCls, configuration={}): if cls.instance is None: cls.instance = NewCls(configuration) Service.boot(Registry, {'a': 'b'}) print Service.get('a') 

    在这里,元类提供了一种适当的方法来将对类的属性访问转移到其属性之一。

    请注意,在Py3下,语法略有不同。 IIRC,是

     class Service(metaclass=DeflectToInstance): 

(但是,仅将Service类用于这种封装对我来说似乎有点错误。

您可以从一个地方的第一个想法开始执行cfg = boot(...) ,然后对每次访问使用cfg 您甚至可能(误导性地)将其命名为Config

class Registry:

    def __init__(self, registrar):
        self.registrar = registrar

    def get(self, key):
        layers = key.split('.')
        value = self.registrar
        for item in layers:
            value = value[item]
        return value

cfg = Registry(...)

要么

Config = Registry(...)

然后在您需要的任何地方使用cfg (或Config )。)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM