instance + classmethod question

Laszlo Zsolt Nagy gandalf at designaproduct.biz
Mon Dec 12 06:42:24 EST 2005


Mike Meyer wrote:

>Laszlo Zsolt Nagy <gandalf at designaproduct.biz> writes:
>  
>
>>Is it possible to tell, which instance was used to call the
>>classmethod that is currently running?
>>    
>>
>
>Ok, I read through what got to my nntp server, and I'm still
>completely confused.
>
>A class method isn't necessarilry called by an instance. That's why
>it's a class method. What should happen in that case?
>  
>
Here is the answer (an example):

    @ClassOrInstanceMethod
    def process_create_table(cls_or_self,tabledef,processor):
        """Process the CREATE TABLE command.

    @param tabledef: a L{TableDefinition} instance.
    @param processor: a L{SQLProcessor} instance."""
        hname = cls_or_self.hashident(tabledef.name)
        if (isinstance(cls_or_self,type)) or (not 
cls_or_self.istableexists(hname)):
            processor.addline("create table %s \n ("% hname)
            for field in tabledef.fields:
                if not (field() is None):
                    
cls_or_self.process_create_table_field(field(),processor)
                    processor.addline(",")
            processor.truncate_last_comma()
            processor.addline("")
            processor.addline(")")
            cls_or_self.addtablespaceclause(tabledef,processor)
            processor.processbuffer()

So if the method was called with an instance, it will check if the table 
exists and create the table only if it did not exist before.
But if the method was called with a class, it will create the table anyway.

The above method is just a short example. I have many methods for 
creating sequences, triggers, constraings etc.
The full pattern is:

def process_XXXXXXX(cls_or_self,defobject,processor):
    <longer code>
   <a condition, depending on the class or the instance>
   <longer code>
   <another condition, depending on the class or the instance>
   <longer code>

There are two reasons why I do not want to create two methods (one 
instance and one class method).

1. If you look the above pattern, it is clear that the method does the 
same thing, just there are some conditions when I call it with an 
instance. I do not want to call "process_create_table_with_class" and 
"process_create_table_with_instance", because the name of the method 
should reflect what it does primarily. (BTW, I also looked at 
multimethods, but they are not exactly for this kind of problem.)

2. The pattern above makes it clear that I just can't easily split the 
method into elementary parts. Steven wrote this pattern:

>class C(object):
>    ...
>    @classmethod
>    def do_stuff(cls, *args):
>        ...
>    def do_instance_stuff(self, *args):
>        # instance stuff
>        ...
>        self.do_stuff(*args)
>        # more instance stuff
>  
>
But I cannot do this, because primarily I do class stuff, and in some 
cases, I can make use of an instance (but do not require it).
Comments welcome

   Les




More information about the Python-list mailing list