gpt4 book ai didi

python 静态 on call 魔术方法

转载 作者:行者123 更新时间:2023-12-01 05:14:13 24 4
gpt4 key购买 nike

我正在尝试构建一个 Service持有 Registry 的类实例。 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 中定义函数类(class)。因此,使用以下代码启动后,我想使用 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)。)

关于python 静态 on call 魔术方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23579227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com