[英]python static on call magic method
我正在尝试建立一个包含Registry
实例的Service
类。 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');
注意:配置对象是注册表的扩展
我已经尝试过__getattr__
魔术方法,但它不适用于静态方法。 我试过__call__
但是之后我需要调用Service().get()
,这不是我想要的。
那么,是否有可能在python中做到这一点? 我不想在Service
层中重新定义类方法。
注意:在PHP中,存在__callStatic()
函数,该函数正是我想要的。 但是,我找不到在python上的实现。
如果您可以稍微修改一下通话方式,我可以想象这是可行的:
cfg = Service.boot(Config, {'a' : 'b'})
cfg.get('a')
这样,如果使boot()
返回提供这些方法的对象,则可以使其与__getattr__
完美配合。
如果没有,您可以尝试以下方法之一:
cfg.instance.get('a')
给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.