当函数具有不同数量的参数时,从列表中调用随机函数

时间:2015-01-04 20:18:06

标签: python list function random arguments

我是一个尝试编写基于文本的游戏的初学者,比如Monopoly。由于我学习了函数,我认为最好的方法是为每个方块定义一个函数。然后,我将函数放在一个列表中并随机调用它们。问题是函数可能需要不同数量的参数或没有参数。

from random import randrange

def foo1(param_of_foo1):
    x = param_of_foo1 + 1
    print "x is:", x

def foo2(param_of_foo2):
    y = param_of_foo2 + 2
    print "y is:", y

def foo3(useless_param):
    print "I have a parameter but I don't really need it..."

list_of_foo = [foo1, foo2, foo3]

arg = 0

function_index = randrange(0,3)

print "Function index is:", function_index

if function_index == 0:
    arg = 4

elif function_index == 1:
    arg = 10

list_of_foo [function_index](arg)

正如您所看到的,这似乎有效,但它不是一个优雅的解决方案。我不喜欢我必须用参数定义第三个函数,当然,即使它不需要它。而且我也不喜欢我必须为某些函数指定一个条件,让他们知道它们应该用作什么参数。 当然必须有更好的方法来做到这一点。总有。谢谢,对不起,如果这是愚蠢的,或者已经被问过。我无法找到答案。

更新的代码:

from random import randrange
from functools import partial

def foo1(arg_of_foo1):
    x = arg_of_foo1 + 1
    print "x is:", x

def foo2(arg1_of_foo2,arg2_of_foo2):
    y = arg1_of_foo2 + arg2_of_foo2
    print "y is:", y

def foo3():
    print "I don't need a parameter so I don't have one."

a = 0
b = 0

while b <= 100:
    print'='*20
    random_number = randrange(0,3)

    a += 1
    b += 10

    print "a is:", a
    print "b is:", b
    print "r_n is:", random_number

    print '-'*10
    raw_input("[Enter] to execute random function")

    list_of_foo = [partial(foo1,a), partial(foo2,a,b), partial(foo3)]

    list_of_foo[random_number]()

此代码删除了条件语句和不必要的参数。 谢谢,检查员!

2 个答案:

答案 0 :(得分:2)

你可以做三件事:

  1. 在功能定义
  2. 中使用*args
  3. 重写您的函数以将列表(或元组或字典)作为唯一参数,并从中读取实际参数
  4. 使用ast读取函数签名,并为其指定正确数量的参数(暂时不在考虑范围内)

  5. 使用*args

    在python中,您可以将*args定义为函数获取的参数列表,这会将参数序列分配给名为args的列表:

    In [113]: def func(*args):
       .....:     print "the arguments are:", ' '.join(args)
       .....:     
    
    In [114]: func()
    the arguments are:
    
    In [115]: func('a')
    the arguments are: a
    
    In [116]: func('a', 'b')
    the arguments are: a b
    

    所以,考虑到这一点,你可以这样做:

    def foo1(*args):
        param_of_foo1 = args[0]  # any other arguments will be discraded
        x = param_of_foo1 + 1
        print "x is:", x
    
    def foo3(*uselessArgs):
        print "I have a parameter but I don't really need it..."
    

    您仍然可以拨打foo3()foo3(1,2,3)


    使用列表

    这与以前的想法相同,但您使用参数列表调用:

    def foo1(L):
        param_of_foo1 = L[0]  # other entries will be ignored
    

    这需要使用参数列表调用:foo1([1])foo1([1,2,3])

    def foo1(arg):
        print "I got this as my argument:", arg
    

    现在,foo1([1,2,3])将提供:

      

    我认为这是我的论点:[1,2,3]

    由于arg的行为与任何其他列表一样(就像在*args情况下一样),你应该能够提取任意数量的参数(只要它们被提供)。因此,由于函数所需的最大参数数为1,因此始终提供至少一个参数的列表,并且将忽略任何其他内容(尤其是foo3

    还有另外一种方法,使用ast,但我不认为这就是你所追求的,所以我现在就把它留下来(评论,我会把它添加进来)


    另一方面,如果你只打算用{4}和foo1打电话给foo2,那么这应该适合你:

    >>> import functools
    >>> import random
    >>> def foo1(param_of_foo1):
    ...     x = param_of_foo1 + 1
    ...     print "x is:", x
    ... 
    >>> def foo2(param_of_foo2):
    ...     y = param_of_foo2 + 2
    ...     print "y is:", y
    ... 
    >>> def foo3(useless_param):
    ...     print "I have a parameter but I don't really need it..."
    ... 
    >>> f = functools.partial(foo1, 4)
    >>> f()
    x is: 5
    >>> list_of_foo = [functools.partial(foo1, 4), functools.partial(foo2, 10), functools.partial(foo3, 'discarded argument')]
    >>> random.choice(list_of_foo)()
    y is: 12
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    y is: 12
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    y is: 12
    >>> random.choice(list_of_foo)()
    I have a parameter but I don't really need it...
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> random.choice(list_of_foo)()
    x is: 5
    >>> 
    

答案 1 :(得分:0)

对于未知数量的参数或未知类型的参数,只需fn(*args)