首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >类属性的python全局装饰器

类属性的python全局装饰器
EN

Stack Overflow用户
提问于 2016-05-15 15:37:31
回答 1查看 2K关注 0票数 2

下面是一段抽象的代码,简化了我遇到的一个问题。在本例中,我有一个具有login和logout属性的程序。登录是独立于版本的,注销是依赖于版本的。

代码语言:javascript
复制
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.loginself.logout。有些继承中,self.logout只是一个字符串,而perform是共享的。

我在想像这样的东西:

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

这显然行不通。这有可能吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-15 16:09:48

手动解决方案

看起来像是property装饰器的用例:

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

现在:

代码语言:javascript
复制
>>> a = A()
>>> a.login
'logged in'
>>> a.logout
'logged out'
>>> a.version = '2.0'
>>> a.logout
'logged out 2.0'     

自动化解决方案1

如果你有很多这样的属性,你可以自动化一点:

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

现在:

代码语言:javascript
复制
>>> 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“都会重新定义属性。此解决方案避免了这种情况,但会涉及更多内容。它利用了类装饰器。

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

现在:

代码语言:javascript
复制
>>> a = A()
>>> a.logout
'goodbye logger'
>>> a.version = '2.0'
>>> a.logout
'goodbye logger 2.0'
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37235698

复制
相关文章

相似问题

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