【问题标题】:How to include a default parameter in a class in Python?如何在 Python 的类中包含默认参数?
【发布时间】:2014-02-22 03:02:00
【问题描述】:

我想在这个 python 类中创建一个默认值。但是当我尝试这样做时,我收到一条错误消息,提示“未定义自我”

我知道答案很简单,但此刻我却不明白。有人知道为什么我不能在这里添加默认参数吗?

提前感谢您的回复!

class Sort(object):
    def __init__(self, lst):
        self.lst = lst

    def halve(self, l = self.lst):### this line <--------------
        n1 = l[:len(l) / 2]
        n2 = l[len(l) /2:]
        return (n1,n2)

【问题讨论】:

  • 参数不能在定义它们的参数列表中使用。

标签: python class default-value


【解决方案1】:

其他人已经展示了您可以如何处理您的问题,但我想澄清一下您的代码无法正常工作的确切原因。

假设你有代码:

def foo(obj, y = obj.x):
    pass

这不起作用的原因与以下不起作用的原因相同:

def foo(x, y = x+2):
    pass

我认为,让您感到困惑的关键在于,“self”这个名字并没有什么特别之处。很容易认为“self”是指代对象的关键词(例如在 ruby​​ 中),但事实并非如此。在 Python 中,对象的方法会自动将对象作为第一个参数传递,而将这个第一个参数称为“self”只是一种惯例。

如果你有一个类、对象和方法调用,例如:

class A(object):
    def foo(self, x, y):
        pass
a = A()
a.foo(1, 2)

您基本上可以将方法调用视为隐式调用:

a.foo(a, 1, 2)

这不是最谨慎的表达方式,但我认为它使想法足够清晰。

【讨论】:

    【解决方案2】:

    即使它看起来对您的目的没有用,您也可以避免使用 None 作为默认占位符,因为您可以使用 *args 将所有参数收集到一个列表中:

    def halve(self, *args):
        if not args: # if arg is an empty list / no arguments given
            lst = self.lst
        else:
            lst = args[0]
        # code
    

    或一行:

    def halve(self, *args):
        lst = self.lst if not args else args[0]
        # code
    

    【讨论】:

      【解决方案3】:

      由于它是方法的参数之一,self 将仅定义在 内部 Sort.halve,而不是在声明它的行上。这意味着在您进入方法之前,您无法访问self.lst

      作为一种解决方法,您可以执行以下操作:

      def halve(self, l=None):
          if l is None:
              l = self.lst
          n1 = l[:len(l) / 2]
          n2 = l[len(l) /2:]
          return (n1,n2)
      

      上面的代码为Sort.halvel参数分配了一个默认值None。调用该方法时,它将使用 if 语句来查看调用者是否为其提供了参数。如果是这样,它将保持l 等于该值。否则,它会将l 分配给self.lst

      【讨论】:

        【解决方案4】:

        不幸的是,你需要指定一个None 默认值并在方法内部检查它是否被传入

        class Sort(object):
            def __init__(self, lst):
                self.lst = lst
        
            def halve(self, l=None):
                if l is None: l = self.lst
                n1 = l[:len(l) / 2]
                n2 = l[len(l) /2:]
                return (n1,n2)
        

        函数的参数是在创建函数时建立的,而不是在调用函数时建立的,所以self.lst还不存在。

        另外,请参阅"Principle of Least Astonishment"

        【讨论】:

        • 类的创建(以及self.lst)不是在创建方法之前吗?这就是我不清楚的地方。
        • 首先创建,但创建instance(以及扩展自身)不会
        • 换一种更简单的方式,当halve 被定义时,__init__ 还没有运行
        • 但实际上,不,它没有。首先创建函数,然后从它们创建类型(类)。
        【解决方案5】:

        解决这个问题的更好方法可能是:

        def halve(self,l=None):
            if l is None:
                l = self.lst
            # code
        

        顺便说一句:请不要将变量命名为l el 或O oh 或I eye。它们在某些字体中看起来像 1 和 0,让每个人的事情变得更加困难。如果您想表明它是一个通用列表,请使用lst,就像您对您的类变量一样!更好的是,用它的含义来命名它:这是一个等级列表吗? grade_list。它是一个数字列表吗? numbers。即使它只是 input_list,它至少比 lst 更易读,而且比 l 更易读

        【讨论】:

        • 这有点有趣,但它最初是 lst。我认为它可能会让人们感到困惑,因为它已经在构造函数中使用(init 方法是否被视为构造函数?)
        • (是的__init__方法被称为构造函数)
        猜你喜欢
        • 1970-01-01
        • 2021-11-19
        • 2012-08-01
        • 1970-01-01
        • 2011-02-10
        • 1970-01-01
        • 2015-11-07
        • 1970-01-01
        相关资源
        最近更新 更多