是否可以声明一个没有参数的函数,但是然后将一些参数传递给该函数而不引发异常?

yur*_*uri 13 python arguments exception

在python中是否可以使用上面的代码而不引发异常?

def myfunc():
    pass

# TypeError myfunc() takes no arguments (1 given)
myfunc('param')
Run Code Online (Sandbox Code Playgroud)

通常在php中,在某些情况下,我启动一个没有参数的函数,然后检索函数内部的参数.

在实践中,我不想在myfunc中声明参数,然后将一些参数传递给它.我找到的唯一解决方案是myfunc(*arg).还有其他方法吗?

Joh*_*ooy 16

有两种方法可以传递args

按位置

>>> def myfunc(*args):
...  print "args", args
...
>>> myfunc("param")
args ('param',)
Run Code Online (Sandbox Code Playgroud)

按关键字

>>> def myfunc(**kw):
...  print "kw", kw
... 
>>> myfunc(param="param")
kw {'param': 'param'}
Run Code Online (Sandbox Code Playgroud)

你可以使用两者组合

>>> def myfunc(*args, **kw):
...  print "args", args
...  print "kw", kw
... 
>>> myfunc("param")
args ('param',)
kw {}
>>>
>>> myfunc(param="param")
args ()
kw {'param': 'param'}
>>>
>>> myfunc("param", anotherparam="anotherparam")
args ('param',)
kw {'anotherparam': 'anotherparam'}
Run Code Online (Sandbox Code Playgroud)


bad*_*adp 14

>>> def myFunc(*args, **kwargs):
...   # This function accepts arbitary arguments:
...   # Keywords arguments are available in the kwargs dict;
...   # Regular arguments are in the args tuple.
...   # (This behaviour is dictated by the stars, not by
...   #  the name of the formal parameters.)
...   print args, kwargs
...
>>> myFunc()
() {}
>>> myFunc(2)
(2,) {}
>>> myFunc(2,5)
(2, 5) {}
>>> myFunc(b = 3)
() {'b': 3}
>>> import dis
>>> dis.dis(myFunc)
  1           0 LOAD_FAST                0 (args)
              3 PRINT_ITEM
              4 LOAD_FAST                1 (kwargs)
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

并实际回答这个问题:不,我不相信还有其他方法.

主要原因很简单:C python是基于堆栈的.不需要参数的函数将不会在堆栈上为其分配空间(myFunc而是将它们放在位置0和1).(看评论)

另外一点是,您将如何访问参数?

  • 堆栈注释除此之外.Python是基于堆栈的,但是参数传递(和解析)不是(参数总是堆栈上的单个项,即使没有参数.)Python不忽略参数的原因是因为它会隐藏错误**. (2认同)

Dan*_*ana 7

当然可以!

您可以像这样定义可变长度参数列表:

def foo(*args):
    print len(args)
Run Code Online (Sandbox Code Playgroud)

args是你的参数的元组,因此调用:

foo(1,2)
Run Code Online (Sandbox Code Playgroud)

为你提供函数内的元组(1,2).


ili*_*iar 5

这是我为此编写的一个函数装饰器,以及一个使用示例:

def IgnoreExtraArguments(f):
    import types
    c = f.func_code
    if c.co_flags & 0x04 or c.co_flags&0x08:
        raise ValueError('function already accepts optional arguments')
    newc = types.CodeType(c.co_argcount,
                   c.co_nlocals,
                   c.co_stacksize,
                   c.co_flags | 0x04 | 0x08,
                   c.co_code,
                   c.co_consts,
                   c.co_names,
                   c.co_varnames+('_ignore_args','_ignore_kwargs'),
                   c.co_filename,
                   c.co_name,
                   c.co_firstlineno,
                   c.co_lnotab,
                   c.co_freevars,
                   c.co_cellvars)
    f.func_code = newc
    return f

if __name__ == "__main__":
    def f(x,y):
        print x+y

    g = IgnoreExtraArguments(f)
    g(2,4)
    g(2,5,'banana')

    class C(object):
        @IgnoreExtraArguments
        def m(self,x,y):
            print x-y

    a=C()
    a.m(3,5)
    a.m(3,6,'apple')
Run Code Online (Sandbox Code Playgroud)