开发者

Python : how to prevent a class variable that is a function to be understood as a method?

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 ...


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


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.


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"!-).


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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜