1

このトピックに従う:ユーザーがAPI関数を「拡張」できるようにする

class Inspector:
    def __init__(self, passedFunc):
        self.passedFunc = passedFunc

    def __call__(self, *args, **kwargs):
        # Inspector needs to generate a list of arguments of the passed function and print them in *correct* order

        # now how to generate a list of arguments using data from both ''args' and 'kwargs'?
        # the user might keep default argument values, in which case both will be None,
        # he might only use args, in which case it is easy,
        # but he might also use kwargs, in which case I don't see how to generate a list with correct order of arguments
        # and he might use all 3 from above together

        # I found this solution for when only default arguments are used
        if args == () and kwargs == {}: args = self.passedFunc.__defaults__

        print args  

@Inspector
def exampleFunc(value=0, otherValue=3):
    pass

exampleFunc()

すべてのシナリオで正しい順序引数リストを生成するにはどうすればよいですか?

4

2 に答える 2

3

これは、デコレーターで実際のパラメーター リストを作成する方法です。

import inspect

class Inspector:
    def __init__(self, passedFunc):
        self.passedFunc = passedFunc

    def __call__(self, *args, **kwargs):

        spec = inspect.getargspec(self.passedFunc)
        params = dict(zip(spec.args, args))
        defaults = dict(zip(spec.args[-len(spec.defaults):], spec.defaults))

        for k, v in kwargs.items():
            if k not in spec.args:
                raise TypeError('unexpected argument', k)
            if k in params:
                raise TypeError('mulitple values for argument', k)
            params[k] = v

        for k in spec.args:
            if k not in params:
                if k in defaults:
                    params[k] = defaults[k]
                else:
                    raise TypeError('missing argument', k)

        args_in_order = [params[x] for x in spec.args]

        print args_in_order

例:

@Inspector
def exampleFunc(value=0, otherValue=3):
    pass

exampleFunc()  # 0,3
exampleFunc('foo')  # foo,3
exampleFunc(otherValue='foo', value=555) # 555,foo
于 2013-01-20T11:41:49.193 に答える
0
In [244]: def myinspector(func):
     ...:     def inner(*args,**kwargs):
     ...:         myrs1=[list(x) for x in zip(func.func_code.co_varnames[-len(func.func_defaults):],func.func_defaults)]
     ...:         if kwargs:
     ...:             for x in myrs1:
     ...:                 if x[0] in kwargs: x[1]=kwargs.get(x[0])
     ...:             for x in kwargs:
     ...:                 if x not in func.func_code.co_varnames: myrs1.append([x,kwargs.get(x)])
     ...:         if args:myrs1=list(args)+ myrs1
     ...:         print myrs1
     ...:     return inner

In [245]: @myinspector
     ...: def exampleFunc(value=0,othervalue=3):
     ...:     pass

In [246]: exampleFunc()
[['value', 0], ['othervalue', 3]]

In [247]: exampleFunc(1,4,5,value=9,name=5)
[1, 4, 5, ['value', 9], ['othervalue', 3], ['name', 5]]

In [248]: exampleFunc(name=5, othervalue=6)
[['value', 0], ['othervalue', 6], ['name', 5]]
于 2013-01-20T12:15:04.153 に答える