Static lambdas in python

南笙酒味 提交于 2020-03-21 16:07:16

问题


I have class in python like this

 import numpy as np
 class BackPropogationNetwork:
        # Static lambdas
        sigmoid = lambda x : 1/(1+np.exp(-x))
        sigmoid_prime = lambda sigmoid: sigmoid(1-sigmoid)

and this is the contructor

 def __init__(self):
    self.some_attr = self.sigmoid(2) 

I get this error

TypeError: <lambda>() takes exactly 1 argument (2 given)

If I call like this

self.some_attr = ClassName.sigmoid()

I get this error

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

回答1:


You need to wrap the lambdas in staticmethod objects:

class BackPropogationNetwork:
    sigmoid = staticmethod(lambda x : 1/(1+np.exp(-x)))
    sigmoid_prime = staticmethod(lambda sigmoid: sigmoid(1-sigmoid))

lambda expressions still produce function objects, just using different (limited) syntax. The same rules apply as defining functions in a class; if you want it to be a static method then you still need to wrap them.




回答2:


So your sigmoid function is kinda independent of the class, it would make sense to keep it outside, unless:

  • you want to not pollute the namespace of the module
  • you want to increase the discoverability of the function
  • you want this method to me overwritten. Let's assume you have made up your mind and nothing can change it, well in that case you can do this. When you call a method like self.method() python passes the the first argument to the funtion the instance self, so either you can make you lambda like this: sigmoid = lambda self, x : 1/(1+np.exp(-x)) or you can do what others have suggested like make it a staticmethod, since staticmethod is a decorator, (function that takes a function) it can be called like this

    In [1]: class A:
       ...:     s = staticmethod(lambda x: x)
       ...:     def a(self):
       ...:         print self.s(10)
       ...:
    
    In [2]: f = A()
    
    In [3]: f.a()
    10
    



回答3:


Your two sigmoid's are not class methods. This means when you call them they expect Class as the implicit first argument.

This error

TypeError: <lambda>() takes exactly 1 argument (2 given)

occurs on this call

self.some_attr = self.sigmoid(2) 

because Class instance object is being passed implicitly along with the int 2. But your sigmoid is defined to accept only one argument.

And I don't think you will get this error

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

with this call

self.some_attr = ClassName.sigmoid()

The error you should get should be something like.

TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'type'

May be you made a copy paste error while typing the question.



来源:https://stackoverflow.com/questions/33307012/static-lambdas-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!