@classmethod question

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Apr 24 01:37:15 EDT 2008


En Thu, 24 Apr 2008 00:27:13 -0300, Scott SA <pydev at rscorp.ab.ca> escribió:

> 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.
>
> 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.

Then you can't use a classmethod. A class method can *only* be called on  
the defining class or a subclass of it, or using an instance of those  
classes, but in any case the first argument (usually called "cls", not  
"self") is the *class* on which you called it.

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

I'm not sure if I get the idea right, but it looks like two different  
classes to me, a Recipe and a RecipeSet:

class Recipe:
     def __init__(self, recipe_name)
         """a Recipe given its name"""

     def get_ingredients(self)
         """a list of ingredients for this recipe"""

class RecipeSet:
     def __init__(self, recipe_names):
         """a set of recipes considered together"""
         self.recipe_names = recipe_names

     def get_ingredients(self)
         """a summarized list of ingredients
         for all given recipes"""


cookie_recipie = Recipe('cookies')
cookie_recipie.get_ingredients()
         2C Flour
         0.5 C Sugar
         ...
all_ingredients = RecipeSet(['cookies','cake','bread']).get_ingrendients()
         8C Flour
         2C Sugar
         ...

-- 
Gabriel Genellina




More information about the Python-list mailing list