我正在尝试构建一个包含Service实例的Registry类。Registry和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 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');注意: Config对象是注册表的扩展
我尝试过__getattr__魔术方法,但它在静态上不起作用。我尝试过__call__,但之后我需要调用Service().get(),这不是我想要的。
那么,在python中有可能做到这一点吗?我不想在Service层中重新定义类方法。
注意:在PHP中,存在完全符合我所需的__callStatic()函数。但是,我在python上找不到实现。
发布于 2014-05-10 09:33:49
如果您能够稍微修改您的呼叫模式,我可以想象它是可行的:
cfg = Service.boot(Config, {'a' : 'b'})
cfg.get('a')通过这种方式,如果让__getattr__返回提供这些方法的对象,则可以完美地使其与boot()一起工作。
如果没有,您可以尝试以下方法之一:
cfg.instance.get('a')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
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)。
https://stackoverflow.com/questions/23579227
复制相似问题