adding a static class to another class

James Stroud jstroud at mbi.ucla.edu
Mon Sep 17 03:04:58 CEST 2007


Nathan Harmston wrote:
> HI,
> 
> I m trying to start an api in a similar way to the djangic way of
> Class.objects.all(). Ie objects is a "Manager" class.
> 
> So:
> 
> class Foo(object):
>    def __init__(self):
>         self.test = "NEE"
> 
> class Manager(object):
>     def __init__(self):
>         pass
>    def all(self):
>        return "COCONUTS"
> 
> Because of how some of the code is set up I cant use
> metaclasses........so I try to use a decorator:
> 
> def addto(instance):
>     def decorator(f):
>         import new
>         f = new.instancemethod(f, instance, instance.__class__)
>         setattr(instance, "objects", f)
>         return f
>     return decorator
> 
> class Manager(object):
>     @addto(Foo)
>     def __init__(self):
>        .............
> 
> however this only binds the init method to the Foo.objects, so not
> what I want. If I try using classmethod...then it just says the
> Foo.objects doesnt exist.
> 
> Does anyone have any ideas how I can accomplish this using decorators?
> And also preventing more than one Manager instance instantiated at one
> time.
> 
> Many Thanks in advance,
> 
> Nathan

What you are trying to do is a little obscure to me, but I think you 
want want to rebind Foo.objects to a new manager every time you 
instantiate a Manager? This will do it:

class Foo(object):
    def __init__(self):
         self.test = "NEE"

class Manager(object):
     def __init__(self):
         pass
     def all(self):
        return "COCONUTS"

def addto(cls):
     def decorator(f):
       def _f(self, *args, **kwargs):
         cls.objects = self
         f(self, *args, **kwargs)
       return _f
     return decorator

class Manager(object):
     @addto(Foo)
     def __init__(self):
       pass

Example:

py> class Foo(object):
...    def __init__(self):
...         self.test = "NEE"
...
py> class Manager(object):
...     def __init__(self):
...         pass
...     def all(self):
...        return "COCONUTS"
...
py> def addto(cls):
...     def decorator(f):
...       def _f(self, *args, **kwargs):
...         cls.objects = self
...         f(self, *args, **kwargs)
...       return _f
...     return decorator
...
py> class Manager(object):
...     @addto(Foo)
...     def __init__(self):
...       pass
...
py> hasattr(Foo, 'objects')
False
py> m = Manager()
py> print m
<__main__.Manager object at 0x121b870>
py> print Foo.objects
<__main__.Manager object at 0x121b870>
py> n = Manager()
py> print n
<__main__.Manager object at 0x121b250>
py> print Foo.objects
<__main__.Manager object at 0x121b250>


If you just want the class Foo to have the class Manager as its objects, 
just do this:

   Foo.objects = Manager

But I don't think that's what you want.

I'm not familiar with django, so if I haven't hit it, please elaborate.

James




More information about the Python-list mailing list