【问题标题】:override getattribute for instance methods and use method input variables覆盖实例方法的 getattribute 并使用方法输入变量
【发布时间】:2018-09-29 23:20:42
【问题描述】:

我有一个类Titles,其中包含生成许多不同标题所需的代码。每个标题方法都接受变量rules,以便灵活地生成正确的标题。无论我调用哪种方法,我都想应用某些格式化步骤。例如,将所有浮点数四舍五入到一个小数位。我试图通过__getattribute__ 执行此操作,但不知道如何将函数变量提供给它(即rules)。这可能吗? __getattribute__ 是否可以访问输入变量?

这是一个简单的例子:

import re
class Titles:
    def __init__(self, name):
        self.name = name
    def __getattribute__(self,attr):
        res = object.__getattribute__(self, attr)() #I need to insert rules here
                                                    #somewhere into the function call
        if isinstance(res, str):
            return re.sub(
                    r'\d+\.\d{1,}', lambda m: format(float(m.group(0)), '.1f')
        return res
    def title(self, rules):
        return '{} has spent {} hours on this project'.format(self.name, rules)    

否则,我想我可以有某种“调用者”方法来调用各种方法,然后在返回之前格式化它们的输出......

【问题讨论】:

    标签: python python-3.x python-2.7 oop getattribute


    【解决方案1】:

    这听起来像是一个装饰器解决方案:

    import re
    class Titles:
        def __init__(self, name):
            self.name = name
        @title_decorator
        def title(self, rules):
            return '{} has spent {} hours on this project'.format(self.name, rules)
    
        @staticmethod
        @title_decorator
        def title2(rules):
            'Also works for {} staticmethods!'.format(rules)
    
    def title_decorator(func):
        def new_function(*args):
            # do something on rules
            func_result = func(*args)
            # do something on func result
            return func_result
        return new_function
    

    我不确定您是否要格式化输出或输入,但您可以同时进行。

    【讨论】:

    • 这听起来确实是处理我的问题的更好方法,谢谢。由于我的一些标题是静态方法(即不要使用自我)而其他标题是实例方法,这个问题变得更加复杂。这意味着调用函数有时会是 func(self, rules),有时只是 func(rules)。您能否提供一个编辑说明如何处理这个问题?
    • @Ludo 嘿,我认为有两种方法可以解决这个问题:1)为不同的场合创建不同的装饰器(一种用于静态,一种用于静态),我认为这是最简单的方法。 2)你可以使用 *args,然后分析输入 ָ(比如说参数的数量)。
    • 看来实际上没有必要对 2) 进行任何分析。只需将 *args 传递给 new_functionfunc。查看编辑 - 为我工作
    • @Ludo 这是一个更好的实现!
    • @Ludo 请注意,为了对规则执行某些操作,您仍然需要分析“规则”在哪个位置(0 或 1 - 静态/实例)。
    最近更新 更多