instance + classmethod question
Steven Bethard
steven.bethard at gmail.com
Sun Dec 11 11:10:30 EST 2005
Laszlo Zsolt Nagy wrote:
>
> Hello,
>
> Is it possible to tell, which instance was used to call the classmethod
> that is currently running?
>
[snip]
>
> processor = SQLProcessors.StdOutProcessor() # Print to stdout
> PostgreSQLConnection.process_create_tables(processor,dbdef) # This
> sould create all tables, using the processor
>
> processor = SQLProcessors.DirectProcessor(conn) # Execute directly
> conn.process_create_tables(processor,dbdef) # This should create
> non-existing tables only, using the processor
>
> Is this possible?
It looks like you want a method that accepts either a class or an
instance. I would typically create two methods, one for the class-based
table-creating, and one for the instance-based table-creating. However,
if you *have* to do it this way, you can introduce your own descriptor
which should give you the behavior you want::
>>> class ClassOrInstanceMethod(object):
... def __init__(self, func):
... self.func = func
... self.classfunc = classmethod(func)
... def __get__(self, obj, objtype=None):
... func = obj is None and self.classfunc or self.func
... return func.__get__(obj, objtype)
...
>>> class C(object):
... @ClassOrInstanceMethod
... def f(*args):
... print args
...
>>> C.f()
(<class '__main__.C'>,)
>>> C().f()
(<__main__.C object at 0x00E73D90>,)
Basically, if the descriptor is called from a type (and thus ``obj is
None``), we return a bound classmethod, and if the descriptor is called
from an instance, we return a bound instance method. Of course this now
means you should write your code something like::
@ClassOrInstanceMethod
def process_create_tables(cls_or_self, processor, dbdef):
...
whose "cls_or_self" parameter gives me a bad code smell. YMMV.
STeVe
More information about the Python-list
mailing list