首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python静态调用魔术方法

python静态调用魔术方法
EN

Stack Overflow用户
提问于 2014-05-10 09:14:12
回答 1查看 820关注 0票数 1

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

代码语言:javascript
复制
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函数。

代码语言:javascript
复制
Service.boot(Config, {'a' : 'b'});
Service.get('a');

注意: Config对象是注册表的扩展

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

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

注意:在PHP中,存在完全符合我所需的__callStatic()函数。但是,我在python上找不到实现。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-10 09:33:49

如果您能够稍微修改您的呼叫模式,我可以想象它是可行的:

代码语言:javascript
复制
cfg = Service.boot(Config, {'a' : 'b'})
cfg.get('a')

通过这种方式,如果让__getattr__返回提供这些方法的对象,则可以完美地使其与boot()一起工作。

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

  1. 打电话给cfg.instance.get('a')
  2. Service一个元类: 类注册中心: def __init__(self,注册员):self.registrar =注册员def get(self,key):layers = key.split('.')value = self.registrar表示层中的项: value = valueitem返回值类DeflectToInstance(type):def __getattr__( selfcls,a):#selfcls以表明它是类对象(因为我们是元类),尝试:#首先,查询类本身返回超级(Meta,selfcls).__getattr__(a),除了AttributeError:# Not,因此,尝试查询实例属性:返回getattr(selfcls.instance,a)类服务:__metaclass__ = DeflectToInstance实例= None @classmethod def引导(cls,NewCls,configuration={}):如果cls.instance是None: cls.instance =NewCls(配置)Service.boot(注册表,{'a':'b'})打印Service.get('a') 在这里,元类提供了一种将属性访问到类的属性转移到其属性之一的适当方法。 请注意,在Py3下,语法略有不同。IIRC,是 类服务(metaclass=DeflectToInstance):

(然而,对于我来说,仅为这种封装使用Service类似乎有点错误。

您可以从我的第一个想法开始在一个地方执行这个cfg = boot(...),然后每次访问都使用cfg。你甚至可以(误导地)把它命名为Config

代码语言:javascript
复制
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(...)

代码语言:javascript
复制
Config = Registry(...)

然后随时随地使用cfg (或Config)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23579227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档