在类中的默认参数中使用 functools.partial 时出现令人惊讶的行为 functools.partial 不参与此行为但是您不能使用尚未创建的类的方法创建部分

问题描述

class A:

    def _add(a,b):
        return a + b
    
    def f_add():
        return _add
    
    def lambda_add():
        return lambda x,y: _add(x,y)
    
    def lambda_arg_add(l=lambda x,y)):
        return l

    def partial_add():
        return partial(_add)
    
    def partail_arg_add(f=partial(_add)):
        return f


A.f_add()(1,2)

A.lambda_add()(1,2)

A.lambda_arg_add()(1,2)

A.partial_add()(1,2)

A.partail_arg_add()(1,2)

除最后一个之外的所有函数调用都会引发错误,指出 _add 未定义,但对 partail_arg_add调用成功执行。这背后的逻辑是什么?为什么解释器在创建偏函数时知道在哪里查找 _add 而只有在它作为认参数完成时才知道?

解决方法

functools.partial 不参与此行为。

这是因为默认 arg 是在函数定义中创建的,在类定义期间,发生在类的范围内,因此您不需要任何“自我”。

这就是为什么这样做:

class Example:
    def A(self):
        pass

    def B(self,x=print(A,1)):
        print(self.A,2)

    print(A,3)

输出:

<function Example.A at 0x7fcf8ebc5950> 1
<function Example.A at 0x7fcf8ebc5950> 3

即使没有调用任何 Example.B(),它也应该在定义类时打印 <function Example.A at 0x7fcf8ebc5950> 1 和 3。

但是您不能使用尚未创建的类的方法创建部分

或者,也许你可以,但我不知道有什么方法可以做到。

我试图修复你的课程:

class A:
    @staticmethod
    def _add(a,b):
        return a + b

    @classmethod
    def f_add(cls):  # valid
        return cls._add

    @classmethod
    def lambda_add(cls):  # valid
        return lambda x,y: cls._add(x,y)

    @staticmethod
    def lambda_arg_add(l=lambda x,y: A._add(x,y)):  # valid
        return l

    @classmethod
    def partial_add(cls):  # valid
        return partial(cls._add)

    @staticmethod
    def partial_arg_add(f=partial(_add)):  # TypeError: 'staticmethod' object is not callable
        return f

但是partial_arg_add 会失败,因为在创建partial 时_add 还不能调用:

class A:
    @staticmethod
    def _add(a,b):
        return a + b

    print(_add(1,3))  # TypeError: 'staticmethod' object is not callable
class A:
    @staticmethod
    def _add(a,b):
        return a + b


print(A._add(1,3))  # 4

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...