Reputation: 18745
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
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
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