Milano
Milano

Reputation: 18745

How to iterate over and filter object methods?

I'm working on a Django project where I have a model Model.

This model has its attributes, methods and subclasses. I want to iterate over and get methods with "statistics" attribute.

So:

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'

Is it possible?

I tried:

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

without success.

EDIT:

This problem can be a solution to more specific Django problem I asked here:

Django - is it possible to iterate over methods?

Upvotes: 1

Views: 181

Answers (2)

Tadhg McDonald-Jensen
Tadhg McDonald-Jensen

Reputation: 21453

You cannot inspect the local variables of a function without executing the function and inspecting during it's execution (or looking at it's bytecode) but you can inspect attributes set on the methods themselves.

I would recommend a decorator that adds the statistic attribute right after definition to mimic the logic of your current setup

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

then instead of statistic = True inside the function you would put @statistics_method right before the definition and the code you currently have would work.

Upvotes: 0

lucasnadalutti
lucasnadalutti

Reputation: 5948

It's not possible because in your example, statistic is not an attribute of your method - it's simply a variable which is limited to the method's scope. In other words, your example is not equivalent to the following:

def want(self):
    # Some code
    return

want.statistics = True

which is a de facto attribute creation, and in which getattr() would actually work.

That said, there's no way to get a list of methods in which there is a variable named statistics.

EDIT

What you probably want is to define a list of methods which you will call in some specific part of your code. Maybe an option is to define these methods in a constant of your model.

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()

Upvotes: 1

Related Questions