关于python:调用类范围中定义的lambda方法(作为类属性)

Calling lambda method defined in class scope (as a class attribute)

1
2
3
4
5
6
7
class _GhostLink(object):
    toGhost = lambda filename: False

class _Mod_AllowGhosting_All(_GhostLink):
    def _loop(self):
        # ...
        if self.__class__.toGhost(fileName) != oldGhost:...

生产:

1
2
3
4
5
6
Traceback (most recent call last):
  File"bash\basher\mod_links.py", line 592, in Execute
    changed = self._loop()
  File"bash\basher\mod_links.py", line 587, in _loop
    if self.__class__.toGhost(fileName) != oldGhost:
TypeError: unbound method <lambda>() must be called with _Mod_AllowGhosting_All instance as first argument (got Path instance instead)

当传递if self.toGhost(fileName) != ...中的实例时,会导致:

1
2
3
4
5
6
Traceback (most recent call last):
  File"bash\basher\mod_links.py", line 592, in Execute
    changed = self._loop()
  File"bash\basher\mod_links.py", line 587, in _loop
    if self.toGhost(fileName) != oldGhost:
TypeError: <lambda>() takes exactly 1 argument (2 given)

为什么toGhost表现为一种classmethodinstance method?

编辑:我知道类、静态等方法的区别-这是一个句法问题


看起来您需要一个静态方法:

1
2
class _GhostLink(object):
    toGhost = staticmethod(lambda filename: False)

或:

1
2
3
4
class _GhostLink(object):
    @staticmethod
    def toGhost(filename):
        return False


发生这种情况的根本原因是lambdadef做了同样的事情,除了def也分配了一个变量,也就是说,两个构造都产生了一个函数。

函数(无论是从lambda还是def到实例方法的绑定,都会发生,因为函数也是描述符;请记住,在每种情况下:

1
foo = lambda (...): (...)

与以下内容相同:

1
2
def foo(...):
    return (...)

所以当你说:

1
2
class _GhostLink(object):
    toGhost = lambda filename: False

就好像你说过:

1
2
3
class _GhostLink(object):
    def toGhost(filename):
        return False

所以这个故事的寓意是,你可能永远不应该使用lambda作为任务的右侧;它与使用def没有"更好"甚至不同。它所做的只是混淆。