views:

117

answers:

4

Hi all !

I am currently implementing a django app, for this I try to use a syntax that is consistent with Django's...

So here is what I am trying :

class Blablabla(Model):

    #this contains Blablabla's options
    class Meta:
        sort_key = lambda e: e

sort_key is a key function (for sorting purposes), but of course, it is understood as Meta's method (which is absolutely not what I want)!!!

Any workaround to this, that would still allow me to use this syntax ?

EDIT : Just an important precision ... the code I wrote is supposed to be written by somebody that uses the library ! That's why I don't want any dirty trick. And YES in Django it is really used just for options... of course Meta IS a class, but I say "it is not seen as a class", because it is not used as a class : you don't instantiate it, you don't put class methods, only class attributes... The Model has a metaclass that extracts everything from this Meta and handles all the options declared... But that's all ! It IS just a placeholder for options.

But OK that's True I never saw an option that is a function in Django... So I'll follow Ned an declare this sorting function as a method of Model that has to be overriden ...

+2  A: 

In general,

class Meta(object):
    sort_key= staticmethod(lambda e: e)

I've no idea if whatever magic Django does to transplant ‘meta’ members copes OK with decorated methods like this, but I don't see any inherent reason why not.

bobince
I don't want to use decorator, because 'Meta' is not really supposed to be seen as a class... It's really just an option placeholder ! So using a decorator in there is not really intuitive...
sebpiq
Sorry, but `Meta` *is* a class, Python won't give you any leeway on that! The only alternative I can think of would be to say `sort_keys= [lambda e: e]` and access `self.sort_keys[0]` to break the connection between the function and the class.
bobince
A: 

The OP writes in a comment "'Meta' is not really supposed to be seen as a class". If that's the case, that is, if Django can survive when Meta is indeed not a class (a very big "if"), then it's possible to satisfy the OP's truly weird desire to avoid the simplest solution (just wrapping stqticfunction around the lambda in question).

Essentially, this requires writing a (pretty weird) meta-class that generates an object where attribute lookup bypasses a class's normal use of descriptor objects (every function is a descriptor object: that is, it has a __get__ method which Python normally uses when looking up attribute on the class or an instance thereof).

The general idea of this absurd gyration would be something like...:

class MetaNotAClass(type):
   def __new__(mcl, clasname, bases, clasdict):
     if bases:
         usedict = {}
     else:
         usedict = clasdict
     usedict['__foo'] = clasdict
     return type.__new__(mcl, clasname, bases, usedict)
   def __getattr__(cls, atname):
      try: return getattr(cls, '__foo')[atname]
      except KeyError: raise AttributeError, atname

class NotAClass:
  __metaclass__ = MetaNotAClass


class Bah(NotAClass):
  def f(): return 'weird!'

print Bah.f()

Of course, anything that expects Bah to be a class will break (but then, you do say it's "not really supposed to be seen as a class", so that's basically what you're asking for: to break any code that believes it is "to be seen as a class"!-).

Alex Martelli
Or you could just define a metaclass that applies `staticfunction` to every method of a class for which it is the metaclass...
Zack
@Zack, yes, but the OP (as part of his absurd request) specifically asks how to avoid "the decorator" (and since nobody's actually proposed using decorator _syntax_, he must mean, avoiding `staticfunction`, the higher-order callable that's often used with decorator syntax, though not in the A the OP was commenting on).
Alex Martelli
I dunno, I understood him to want "staticfunction" not to appear on or near the "sort_key = lambda e: e" line.
Zack
+2  A: 

Why are you trying to put sort_key into Meta? Meta is used for Django options, it isn't a place to put your own methods. Models can have methods defined on them. I think you want something as simple as:

class Blablabla(Model):

    def sort_key(self, e):
        return e
Ned Batchelder
Actually I think that might be the best solution :)I was just thinking of considering "sort_key" as an option, so it would be a reusable sorting function, instead of being a method ...
sebpiq
You could make it a staticmethod on the model as well!
lazerscience
that's what I did ! Thanks :)
sebpiq
A: 

Can't you just create a simple module (meta?) and add sort_key to it? Then go ahead and include it wherever you need it...

Daren Thomas