adding a static class to another class

N

Nathan Harmston

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
 
T

thebjorn

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

You want to use descriptors (classes that implement __get__, __set__,
__del__). Google for the particulars.

-- bjorn
 
J

James Stroud

Nathan said:
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
 
J

James Stroud

James said:
Forgot to answer this. You want the singleton pattern:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52558

But not really a singleton now that I think about it...

class Singletonish(object):
""" A python singletonish """

class __impl(object):
""" Implementation of the singletonish interface """

def spam(self):
""" Test method, return singletonish id """
return id(self)

# storage for the instance reference
__instance = None

def __init__(self):
""" Create singletonish instance """
Singletonish.__instance = Singletonish.__impl()

def __getattr__(self, attr):
""" Delegate access to implementation """
if attr == '__id__':
return id(Singletonish.__instance)
return getattr(Singletonish.__instance, attr)

def __setattr__(self, attr, value):
""" Delegate access to implementation """
return setattr(Singletonish.__instance, attr, value)


In action:

py> class Singletonish(object):
.... """ A python singletonish """
.... class __impl(object):
.... """ Implementation of the singletonish interface """
.... def spam(self):
.... """ Test method, return singletonish id """
.... return id(self)
.... # storage for the instance reference
.... __instance = None
.... def __init__(self):
.... """ Create singletonish instance """
.... Singletonish.__instance = Singletonish.__impl()
.... def __getattr__(self, attr):
.... """ Delegate access to implementation """
.... return getattr(Singletonish.__instance, attr)
.... def __setattr__(self, attr, value):
.... """ Delegate access to implementation """
.... return setattr(Singletonish.__instance, attr, value)
....
py> s = Singletonish()
py> print s.spam()
18727248
py>
py> t = Singletonish()
py> print t.spam()
18682480
py> print s.spam()
18682480


Of course t and s are not /really/ the same:


py> print id(t)
18727056
py> print id(s)
18727280
py> assert t is s
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
<type 'exceptions.AssertionError'>


But this shouldn't matter unless you have a special use case because the
implementation to all Singletonish objects are delegated to to the
latest __impl object and so behave identically.

James
 
B

Bruno Desthuilliers

Nathan Harmston a écrit :
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.
Indeed.

If I try using classmethod...then it just says the
Foo.objects doesnt exist.

You mean decorating Manager.__init__ with classmethod ???

I may be wrong, but I suspect you don't have a clear idea of what you're
doing here.
Does anyone have any ideas how I can accomplish this using decorators?

Yes : don't use a decorator !-)

Instead of asking for how to implement what you think is the solution,
you might be better explaining the problem you're trying to solve.
And also preventing more than one Manager instance instantiated at one
time.

Q&D:

class Singleton(object):
def __new__(cls):
if not hasattr(cls, '_inst'):
cls._inst = object.__new__(cls)
return cls._inst


Same remark as above...
 
N

Nathan Harmston

Hi,

I guess my description was a bit rubbish in retrospec, I dont even
think the title of my email made sense....it doesnt to me now:

class Manager(object):
def __init__(self):
pass
def dosomething(self):
return "RESULTS"

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

What I m trying to do is end up with the following syntax:

f = Foo() # instantiates a Foo object
g= Foo.objects.dosomething() # returns "RESULTS"

The best way I ve found of doing this is overriding new

class Foo(object):
def __new__(cls, *args, **kw):
cls.objects = Manager()

----> If I do it like this, I get exactly what I want - especially if
I change the new method in Manager to one supplied by Bruno.

However, I m playing around with SQLAlchemy (which is going to be used
by some of the Managers I create, others will use different things)
which means that overriding new is not allowed, I cant assign a mapper
to Foo.

So I was trying to think of another way of doing cls.objects =
Manager()....and the only solution I could think of was to use a
decorator and try to do it somehow.......
From Brunos answer I guess a decorator is not a good way of
accomplishing this, so if there anyway of doing this without using a
metaclass......or by using a decorator or not....any help would be
greatly appreciated.

Many Thanks in advance

Nathan
 
B

Bruno Desthuilliers

Nathan Harmston a écrit :
Hi,

I guess my description was a bit rubbish in retrospec, I dont even
think the title of my email made sense....it doesnt to me now:

class Manager(object):
def __init__(self):
pass
def dosomething(self):
return "RESULTS"

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

What I m trying to do is end up with the following syntax:

f = Foo() # instantiates a Foo object
g= Foo.objects.dosomething() # returns "RESULTS"

The best way I ve found of doing this is overriding new

class Foo(object):
def __new__(cls, *args, **kw):
cls.objects = Manager()

You're obviously overcomplexifying things here...

# the canonical pythonic way
class Foo(object):
objects = Manager()

def __init__(self):
self.a = "NEE"


# the monkeypatch way
class Foo(object):
def __init__(self):
self.a = "NEE"

Foo.objects = Manager()



HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,191
Latest member
BuyKetoBeez

Latest Threads

Top