【问题标题】:How to iterate over and filter object methods?如何迭代和过滤对象方法?
【发布时间】:2017-04-25 06:25:38
【问题描述】:

我正在开发一个 Django 项目,其中有一个模型模型。

这个模型有它的属性、方法和子类。我想迭代并获取具有“统计”属性的方法。

所以:

class Model(models.Model):
    name = ...

    def dont_want(self):
        return 'foo'

    def want(self):
        statistic = True
        return self.name

    def want_too(self):
        statistic = True
        return self.name

    def get_methods_with_statistic_attribute(self):
        # WHAT TO DO
        return methods 


model = Model(name='Peter')
for method in model.get_methods_with_statistic_attribute():
    print method

>>> 'Peter'
>>> 'Peter'

有可能吗?

我试过了:

return [a for a in dir(self) if hasattr(getattr(self,a),'statistic')] 

没有成功。

编辑:

这个问题可以解决我在这里提出的更具体的 Django 问题:

Django - is it possible to iterate over methods?

【问题讨论】:

  • 技术上,您可以通过执行类似'statistic' in getattr(self,a).__func__.__code__.co_varnames 之类的操作来找到其中定义了一个名为statistic 的局部变量的方法,但这不会告诉您它在函数内部的用途,也不是在全部推荐。

标签: python python-2.7 class methods


【解决方案1】:

如果不执行函数并在其执行期间进行检查(或查看其字节码),则无法检查函数的局部变量,但您可以检查方法本身上设置的属性。

我会推荐一个装饰器,在定义之后添加 statistic 属性以模仿当前设置的逻辑

def statistics_method(func):
    func.statistic = True
    return func

然后,您可以将@statistics_method 放在函数之前,而不是函数中的statistic = True,并且您当前拥有的代码将起作用。

【讨论】:

    【解决方案2】:

    这是不可能的,因为在您的示例中,statistic 不是您的方法的属性 - 它只是一个仅限于方法范围的变量。换句话说,您的示例等同于以下内容:

    def want(self):
        # Some code
        return
    
    want.statistics = True
    

    这是一个事实上的属性创建,getattr()实际上会在其中工作。

    也就是说,没有办法获得包含名为statistics 的变量的方法列表。

    编辑

    您可能想要的是定义一个方法列表,您将在代码的某些特定部分调用这些方法。也许一种选择是在模型的常量中定义这些方法。

    class Model(models.Model):
        name = ...
        USEFUL_METHODS = ['want', 'want_too']
    
        def dont_want(self):
            return 'foo'
    
        def want(self):
            statistic = True
            return self.name
    
        def want_too(self):
            statistic = True
            return self.name
    
    # ...
    
    instance = Model()
    for method_str in Model.USEFUL_METHODS:
        method = getattr(instance, method_str)
        method()
    

    【讨论】:

    猜你喜欢
    • 2021-12-25
    • 2014-10-27
    • 2021-10-13
    • 1970-01-01
    • 2014-01-01
    • 2015-08-08
    • 1970-01-01
    • 2020-07-28
    • 2019-06-13
    相关资源
    最近更新 更多