Python:按名称传递条件参数

时间:2014-04-30 18:44:01

标签: python

我有一堆函数,其中一些需要bar参数,其中一些需要foo参数,其中一些不需要,有些则需要两者。

我希望从同一个位置调用所有这些函数,因为函数是从变量引用的。

我找到的可能解决方案是:

  1. function(bar =“some_value”,foo =“other value”)
  2. 使用inspect然后检测需要传递的参数
  3. 我不相信#1会起作用,但我知道#2会。是否有本地(不使用图书馆)方式让我这样做?

    举个例子:

    functions = [lambda foo: foo.do_something(),
                 lambda bar: bar.do_something_else(),
                 lambda foo, bar: foo.something_with_bar(bar),
                 lambda: do_another_task()
    ]
    for function in functions:
        //call goes here
    

    注意:我实际上有很多很多函数需要用这些参数调用,并且它们并不是很好地存储在数组中。如果我能在不改变功能的情况下做到这一点,我更愿意。

2 个答案:

答案 0 :(得分:3)

最好将 lambda表达式存储在变量中,而不是基础函数中,并将参数绑定在lambda中。类似的东西:

foo = 'foo'
bar = 'bar'
if funcname == 'a':
  func = a  # a takes no args
elif funcname == 'b':
  func = lambda: bb(bar=bar)  # bb takes bar
elif funcname == 'c':
  func = lambda: ccc(foo=foo)  # ccc takes foo
# call it, uniformly
func()

类似的方法是"解除绑定":

if funcname == 'a':
  func = lambda foo, bar: a()  # don't pass foo and bar
elif funcname == 'b':
  func = lambda foo, bar: bb(bar=bar)  # don't pass foo
elif funcname == 'c':
  func = lambda foo, bar: ccc(foo=foo)  # don't pass bar
# call it, uniformly
func(foo, bar)

此外,如果您想重构代码以使其更优雅和面向对象,请定义接口和外观实现:

class FooBarInterface(object):
    def f(self, foo, bar):
        raise NotImplementedError
class A(FooBarInterface):
    def f(self, foo, bar):
        return a()
class B(FooBarInterface):
    def f(self, foo, bar):
        return bb(bar=bar)
class C(FooBarInterface):
    def f(self, foo, bar):
        return ccc(foo=foo)

if funcname == 'a':
  obj = A()
elif funcname == 'b':
  obj = B()
elif funcname == 'c':
  obj = C()
# call it, uniformly
obj.f()

请不要使用内省。它会使你的代码变得比需要的更复杂。

答案 1 :(得分:0)

除非您可以自己编辑功能,否则无法原生地执行此操作,如果您有可能

def func_a(**kwargs):
    foo = kwargs['foo']
    # or even:
    foo = kwargs.get('foo', None) # in case foo wasn't passed the the function
    ...

def func_b(**kwargs):
    bar = kwargs.get('bar', None)
    ...

通过这种方式设置功能,您可以传递任何您喜欢的关键字参数。