【问题标题】:python instance variables as optional argumentspython实例变量作为可选参数
【发布时间】:2009-05-15 05:40:57
【问题描述】:

在 python 中,有没有一种方法可以在类方法中使用实例变量作为可选参数?即:

def function(self, arg1=val1, arg2=val2, arg3=self.instance_var):
    # do stuff....

任何帮助将不胜感激。

【问题讨论】:

    标签: python function class


    【解决方案1】:

    试试这个:

    def foo(self, blah=None):
        if blah is None: # faster than blah == None - thanks to kcwu
            blah = self.instance_var
    

    【讨论】:

    • 使用“is”来比较 None 更好(更快)
    • @kcwu 感谢您的建议。我知道它们是不同的,但我做了一个基准测试并发现了很大的性能差异。
    • @kcwu 嗯,这很有趣,使用“is”比较字符串也表明它快了 50%。但是,这不适用于整数。
    • 不要将字符串与“is”进行比较,除非您确实想比较引用而不是值。
    • @Unknown - 并非总是如此。 Python 会根据它们的创建方式等来实习一些字符串,但不是全部。尝试 ('%s%s' %('x','y')) 改为 ('%s%s' % ('x','y')) ,或者从文件中读取两个相同的字符串。
    【解决方案2】:

    所有提示None的回答都是正确的;如果您想确保调用者可以将 None 作为常规参数传递,请使用特殊的 sentinel 并使用 is 进行测试:

    class Foo(object):
      __default = object()
      def foo(self, blah=Foo.__default):
        if blah is Foo.__default: blah = self.instavar
    

    object() 的每次调用都会生成一个唯一的对象,因此is 在它和任何其他值之间永远不会成功。 __default 中的两个下划线表示“高度私有”,这意味着调用者知道他们不应该尝试弄乱它(并且需要做相当多的工作才能这样做,明确地模仿编译器正在做的名称修改)。

    顺便说一句,您不能只使用您发布的代码的原因是默认值在 def 语句评估时评估,而不是在调用时稍后;在 def 计算时,还没有 self 可以从中获取实例变量。

    【讨论】:

      【解决方案3】:

      不,因为类函数定义时实例不存在

      你必须重写如下

      def function(self, arg1=val1, arg2=val2, arg3=None):
          if arg3 is None:
              arg3 = self.instance_var
      

      这与原来的略有不同:如果你真的想要,你不能传递带有 None 值的 arg3。

      替代解决方案:

      def function(self, arg1=val1, arg2=val2, **argd):
          arg3 = argd.get('arg3', self.instance_var)
      

      【讨论】:

        【解决方案4】:
        def foo(self, blah=None):
            blah = blah if not blah is None else self.instance_var
        

        这适用于 python 2.5 并转发和处理 blah 为空字符串、列表等的情况。

        【讨论】:

          【解决方案5】:

          另一种方法是:

          def foo(self, blah=None):
              blah = blah or self.instance_var
          

          这个较短的版本看起来更好,特别是当有多个可选参数时。

          小心使用。请参阅下面的 cmets...

          【讨论】:

          • 或 False 或空数组...简短:不要这样做
          • 正如其他评论者指出的那样,这并不是真正的 Pythonic,因为它具有意想不到的效果。
          • 你没关系。我仍然认为它很有帮助,例如字符串。
          猜你喜欢
          • 1970-01-01
          • 2013-06-23
          • 2011-08-26
          • 1970-01-01
          • 2013-07-12
          • 2020-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多