@classmethod question
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Thu Apr 24 04:46:25 EDT 2008
Scott SA a écrit :
> Hi,
>
> I'm using the @classemethod decorator for some convenience methods
> and for some reason, either mental block or otherwise, can't seem to
> figure out how to elegantly detect if the call is from an instance or
> not.
Well, the point is that a classmethod *always* receive the class as
first argument, wether it's called on the class or an instance. If
that's not what you want, then you don't use the right tool.
> Here's the problem: Within the class definition, 'isinstance' has
nothing to compare to because the class does not appear to exist.
>
> This is NOT a great example, but it outlines the the code: >
> class RecipieClass:
> def __init__(self):
> pass
>
> @classmethod
> def get_ingrendients(self, recipie_list=None):
>
> if isinstnace(self,RecipieClass):
> return self.do_something_interesting()
> else:
> return do_something_boring(recipie_list)
>
> Yes, I can test to see if the param exists, but that makes the call
> exclusive i.e. I can _only_ call it as an instance or with a parameter.
>
> Why am I doing this?
>
> It is a series of convenience methods, in this case I'm interacting
> with a database via an ORM (object-relational model).
out of curiosity : which one ?
> I want the ability
> to call a class-ojbect and get related values, or pass some criteria and
> get related values for them without collecting the records first as
> instances, then iterating them. I need to call this from several places
> so I want to be DRY (don't repeat yourself).
>
> The easiest way to describe this as an analogy would be like having a
> recipie for cookies and wanting to know all of the ingredients ahead of
> time. Then, at another time, wanting to know what all the ingredients
> would be to make cookies, cake and bread (i.e. complete shopping list).
> cookie_recipie = RecipieClass.get_recipie('cookies')
> cookie_recipie.get_ingredients()
> 2C Flour
> 0.5 C Sugar
> ...
>
> RecipieClass.get_ingrendients(['cookies','cake','bread'])
> 8C Flour
> 2C Sugar
> ...
> Of course any suggestions on how this might be better approached
would > be interesting too.
Why do you want the same method to do two different things ? You clearly
have two distincts methods doing different things here, and as a user of
your code I'd find your API confusing. May I suggest a much simpler
approach:
class Recipies(object):
@property
def ingredients(self):
return <dict of ingredient:qty for self>
@classmethod
def get_ingredients_for(cls, *id_recipies):
return <dict of ingredient:summed_qty for all id_recipies>
print Recipie.get('cookie').ingredients
print Recipies.get_ingredients_for('cookie', 'cake', 'bread')
My 2 cents...
More information about the Python-list
mailing list