下面是一段抽象的代码,它简化了我遇到的问题。在此示例中,我有一个具有登录和注销属性的程序。登录名与版本无关,而注销则与版本有关。
class A(class):
def __init__(self):
self.version = "1.0"
self.login = "logged in"
self.login_message = "hello logger"
self.logout = {"1.0": "logged out",
"2.0": "logged out 2.0"}
self.logout_message = {"1.0": "goodbye logger",
"2.0": "goodbye logger 2.0"}
def perform(self, executor):
executor.do(self.login)
executor.do(self.logout)
executor
是执行实际操作的外部接口,它应该接收一个字符串。该do
功能无法更改。该版本可以并且将在运行时更改,因此我一直在寻找某种全局装饰器/属性,当访问装饰的属性时,该装饰器/属性将调用一个函数。目的是在将每个版本发送到之前为每个版本选择正确的字符串executor.do
。
答案显然是改变perform
功能executer.do(self.logout[self.version])
,但self.login
并self.logout
不宜不同的方式访问。有些继承self.logout
仅是一个字符串,并且perform
被共享。
我在想类似的东西:
self.version = "1.0"
self.login = "logged in"
self.login_message = "hello logger"
@by_version
self.logout = {"1.0": "logged out",
"2.0": "logged out 2.0"}
@by_version
self.logout_message = {"1.0": "goodbye logger",
"2.0": "goodbye logger 2.0"}
def by_version(self, attribute):
return attribute[self.version]
那显然是行不通的。这有可能吗?
看起来像一个property
装饰器的用例:
class A(object):
def __init__(self):
self.version = "1.0"
self.login = "logged in"
self.login_message = "hello logger"
@property
def logout(self):
return {"1.0": "logged out", "2.0": "logged out 2.0"}[self.version]
@property
def logout_message(self):
return {"1.0": "goodbye logger", "2.0": "goodbye logger 2.0"}[self.version]
现在:
>>> a = A()
>>> a.login
'logged in'
>>> a.logout
'logged out'
>>> a.version = '2.0'
>>> a.logout
'logged out 2.0'
如果您有很多这样的属性,则可以自动化一些:
class A(object):
def __init__(self):
self.version = '1.0'
self.login = 'logged in'
self.login_message = 'hello logger'
property_attrs = {'logout': {'1.0': 'logged out',
'2.0': 'logged out 2.0'},
'logout_message': {'1.0': 'goodbye logger',
'2.0': 'goodbye logger 2.0'}}
for name, value in property_attrs.items():
setattr(self.__class__, name, property(lambda x: value[x.version]))
现在:
>>> a = A()
>>> a.login_message
'hello logger'
>>> a.logout
'goodbye logger'
>>> a.version = '2.0'
>>> a.logout
'goodbye logger 2.0'
每次创建的新实例时,“自动化解决方案1”都会重新定义属性A
。该解决方案避免了这种情况,但是涉及更多。它使用了一个类装饰器。
property_attrs = {'logout': {'1.0': 'logged out', '2.0': 'logged out 2.0'},
'logout_message': {'1.0': 'goodbye logger', '2.0': 'goodbye logger 2.0'}}
def add_properties(property_attrs):
def decorate(cls):
for name, value in property_attrs.items():
setattr(cls, name, property(lambda self: value[self.version]))
return cls
return decorate
@add_properties(property_attrs)
class A(object):
def __init__(self):
self.version = '1.0'
self.login = 'logged in'
self.login_message = 'hello logger'
现在:
>>> a = A()
>>> a.logout
'goodbye logger'
>>> a.version = '2.0'
>>> a.logout
'goodbye logger 2.0'
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句