下面是一段抽象的代码,简化了我遇到的一个问题。在本例中,我有一个具有login和logout属性的程序。登录是独立于版本的,注销是依赖于版本的。
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]
这显然行不通。这有可能吗?
发布于 2016-05-15 16:09:48
手动解决方案
看起来像是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'
自动化解决方案1
如果你有很多这样的属性,你可以自动化一点:
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'
自动化解决方案2
每次创建新的A
实例时,"Automated Solution 1“都会重新定义属性。此解决方案避免了这种情况,但会涉及更多内容。它利用了类装饰器。
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'
https://stackoverflow.com/questions/37235698
复制相似问题