Lambda @classmethod call not executing

I may be completely wrong, but I ran into some odd issues with the @classmethod lambda call.

I have the following class:

class MyClass: LAMBDA = lambda: MyClass.ClassMethod() @classmethod def ClassMethod(cls): pass 

But this does not work when calling LAMBDA with:

 TypeError: unbound method <lambda>() must be called with MyClass instance as first argument (got nothing instead) 

I really don’t understand why this is so. I have already spent some time trying to get this job done. I need some class attributes to be filled with this lambda and class self-regulation is obviously not possible at this point.

+6
python
source share
4 answers

You must understand that your code is exactly equivalent.

 class MyClass: def LAMBDA(): return MyClass.ClassMethod() @classmethod def ClassMethod(cls): pass 

You apparently call it MyClass.LAMBDA() . But look, LAMBDA is an instance method. And you call it without an actual instance.

What exactly are you trying to do?

I believe that if you give the name of a lambda construct, you can also declare it in the "normal" way - def . In my experience, there are only a few isolated cases where using lambas really contributes to the quality of the code.

+2
source share

LAMBDA is just a normal method here. When you look at a class, you get an unrelated method, which is kind of a dumb thing that takes your function and imposes this, although self has not yet been passed - the first argument should be an instance of the class in question.

To repeat, LAMBDA = lambda: MyClass.ClassMethod() no different from def LAMBDA(): return MyClass.ClassMethod() . In the latter case, it is more clear that you have a kind of broken method definition. The lambda function and the def function form the same types of objects, and Python turns them into methods with the same rules on the fly during the search.

I suspect the code you may need

 class MyClass(object): @classmethod def ClassMethod(cls): pass MyClass.LAMBDA = MyClass.ClassMethod 

or

 class MyClass(object): @classmethod def ClassMethod(cls): pass @classmethod def LAMBDA(cls): return cls.ClassMethod() 

(Note that this last can be written using lambda, as you originally did, but there is no reason. I would never use = lambda in any of my code personally. Also note that ClassMethod and LAMBDA do not follow normal rules Python capitalization style.)

+2
source share

There is another direct solution. Maybe this is not the purest thing, but I think that this is what you are interested in. I myself faced a similar situation. You can intentionally untie it with staticmethod() .

Here's the erroneous version:

 def bar(): return 0 class foo(object): x = lambda:bar() @classmethod def grok(klass): return klass.x() foo().grok() Traceback (most recent call last): File "<console>", line 1, in <module> File "<console>", line 4, in grok TypeError: unbound method <lambda>() must be called with foo instance as first argument (got nothing instead) 

And a slightly adjusted version:

 def bar(): return 0 class foo(object): x = staticmethod(lambda:bar()) @classmethod def grok(klass): return klass.x() foo().grok() 0 

Please note that both of them also have a place for:

  x = bar 

Instead. I just included lambda in the direct answer to this question. All of the above suggestions also work, it's just a direct way to change the code as little as possible.

As for why someone would like to do something like the above working with lambda? In my case, I was making a factory class that had event handlers that would sometimes use class data to retrieve information, and part of this information was of value or called. (This was for the Django form.) Thus, the “called” was a direct lambda passed by the user, which had to be called using self.value() or klass.value() , but value was an unbound function (lambda or otherwise).

+1
source share

I need some class attributes populated by this lambda, and class self-regulation at this stage is clearly impossible.

But from your given code, everything LAMBDA will do when it is called, it calls MyClass.ClassMethod() , which means that the method that performs the population is ClassMethod (this, of course, assumes that the body of ClassMethod is actually not the only pass . which you showed because if she does this, this exercise is useless). If any aspect of your code does not allow you to access the class before using it for anything, why can't you call MyClass.ClassMethod() after the class is defined?

And if you are trying to change the class attributes inside the definition (that is, by calling LAMBDA in the MyClass definition, outside of any methods / functions / independently), you can take a look at the metaclass documentation section.

On the side of the note, if you want to assign attributes to a class, you don't even need to do this inside the body of the class itself.

 >>> class cls(object): # or just "class cls:" ... pass ... >>> cls.value = 10 >>> cls.name = 'class' >>> cls.value 10 >>> cls.name 'class' >>> dir(cls) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'value'] 
0
source share

All Articles