将self.var(实例属性)作为默认方法参数传递

7
在函数 fiz 中赋值 num1 = self.var1 时,Python 报告未解决的引用错误。为什么会这样呢?
class Foo:

    def __init__(self):
        self.var1 = "xyz"

    def fiz(self, num1=self.var1):
        return

3
默认值不能引用其他参数,包括 self,因为它们不在“同一作用域”中。实际上,这些值在方法运行之前就已经解析了。这也是为什么 def f(my_list=[]) 每次调用时不会创建一个新列表的原因之一... 一种处理方法是使用 def fiz(self, num1=None): if num1 is None: num1 = self.var1.. 如果在“未指定”和“为None”之间有区别,则可以使用kwargs。 - user2864740
在类定义内部,self 不在作用域内 - 在完成类的定义之前,您不能拥有实例!只需使用 None 作为默认值,然后在方法内设置 num1 = self.var1 if num1 is None else num1 - jonrsharpe
1个回答

7

方法(和函数)的默认参数值在定义方法时就已经确定了。当这些值是可变的时,这会导致 Python 中常见的一个问题:“最少惊奇”和可变默认参数

在你的情况下,在定义方法时并没有 self 可用(如果有这样的名称在作用域中,由于你尚未完成定义类 Foo,它不会是 Foo 实例!)你也不能在定义内部引用该类名;引用 Foo 也会导致 NameError我可以使用类属性作为实例方法的默认值吗?

相反,常见的做法是使用 None 作为占位符,然后在方法体内分配默认值:

def fiz(self, num1=None):
    if num1 is None:
        num1 = self.val1
    ...

1
@BillalBEGUERADJ 因为最初我没有找到重复的内容,所以写了一个答案,然后想到另一个搜索词,成功地找到了一个重复的。现在我无法删除这个答案,因为它已被接受。 - jonrsharpe
为什么在函数属性中可以引用self,但不能将其作为其中一个属性的默认值? - Hedwin Bonnavaud
我的意思是在开括号后的第一个单词是“self”。如果“定义方法时没有‘self’可用”,那么这是怎么可能的呢? - Hedwin Bonnavaud
1
@HedwinBonnavaud 这不是“引用”,而是“定义”。 在函数被“调用”之前,它没有可引用的“值”。 - jonrsharpe
1
(请注意这些是参数,而不是属性@HedwinBonnavaud。函数对象也可以有属性,但这不是我们讨论的重点。) - jonrsharpe
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接