【问题标题】:Equivalent of ruby obj.send in pythonpython中ruby obj.send的等价物
【发布时间】:2011-07-11 11:03:31
【问题描述】:

在 ruby​​ 中,如果我有一个对象 obj,使用一个名为 funcname 的方法,我可以使用以下语法调用该方法 obj.send(funcname)

python中是否有类似的东西。

我想这样做的原因是,我有一个 switch 语句,我在其中设置了 funcname,并且想在 switch 语句的末尾调用它。

【问题讨论】:

  • Python 没有 switch 语句。此外,在运行时生成函数名称几乎总是一个坏主意。
  • @Rafe:通常不需要它,但它本身并没有什么坏处。
  • 是的,它没有,但我仍然想在 if-elif-else 循环中进行。我想我在下面得到了答案。
  • 你总是可以只分配函数:“f = obj.func”,然后再调用f(args)。 Python 的方法绑定在需要时非常适合。

标签: python send


【解决方案1】:
getattr(obj, "name")(args)

​​​​​

【讨论】:

    【解决方案2】:

    嗯... getattr(obj, funcname)(*args, **kwargs) ?

    >>> s = "Abc"
    
    >>> s.upper()
    'ABC'
    
    >>> getattr(s, "upper")()
    'ABC'
    
    >>> getattr(s, "lower")()
    'abc'
    

    【讨论】:

      【解决方案3】:

      除了已经提到的getattr()内置:

      作为 if-elif-else 循环的替代方案,您可以使用字典将“案例”映射到所需的函数/方法:

      # given func_a, func_b and func_default already defined
      function_dict = {
          'a': func_a,
          'b': func_b  
      }
      x = 'a'
      function_dict(x)() # -> func_a()
      function_dict.get('xyzzy', func_default)() # fallback to -> func_c
      

      关于方法而不是普通函数:

      • 您可以将上面的示例转换为method_dict,例如使用lambda obj: obj.method_a() 而不是function_a 等,然后执行method_dict[case](obj)
      • 您可以使用getattr(),正如其他答案已经提到的那样,但只有当您确实需要从其名称中获取方法时才需要它。
      • 在某些情况下,来自 stdlib 的operator.methodcaller() 是一个不错的快捷方式:基于方法名称和可选的一些参数,它创建一个函数,该函数在另一个对象上调用具有该名称的方法(如果您在创建methodcaller,它将使用这些参数调用方法)

      【讨论】:

        【解决方案4】:

        或者,如果您愿意,operator.methodcaller('foo') 是一个函数,它在您传递的任何内容上调用 foo。换句话说,

        import operator
        fooer = operator.methodcaller("foo")
        fooer(bar)
        

        等价于

        bar.foo()
        

        (我认为这可能是合适类别中的伴随词或对偶词。如果您有数学倾向。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-12
          • 1970-01-01
          • 2012-04-07
          • 1970-01-01
          • 1970-01-01
          • 2016-06-21
          • 2010-09-20
          相关资源
          最近更新 更多