Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

python - Can you determine from a function, args, and kwargs, how variables will be assigned?

I have some boiler plate logic that I want to wrap several functions that have the same optional keyword. Right now it looks like the code below. However, this only handles the case that opt_key is passed as a keyword, as opposed to being passed positionally. One way to solve this would be to know how the argument assignment would be resolved.

Is there some meta function that take a function, args, and kwargs, and returns a dictionary that gives the map from variable names to values? So for below,

meta_function(g,1,2,3) would return {"x" : 1, "y" : 2, "opt_key" : 3} and

meta_function(g,1,2,opt_key=3) would also return {"x" : 1, "y" : 2, "opt_key" : 3}

def g(x,y,opt_key = None):
  return something

def h(z,opt_key = None):
  return something else

def wrap(f,*args,**kwargs):
  if kwargs["opt_key"] is None:

    #Do some stuff to get default opt_key

    kwargs["opt_key"] = default_opt_key
    v = f(args,kwargs)

    #Do some stuff to dispose default opt_key

    return v
  else:
    return f(args,kwargs)

wrap(g,x,y,opt_key = None)
wrap(h,x,opt_key = None)
question from:https://stackoverflow.com/questions/65905885/can-you-determine-from-a-function-args-and-kwargs-how-variables-will-be-assig

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes, you want to use inspect.signature and work with the Signature object, which will allow you to .bind *args and **kwargs:

In [1]: import inspect

In [2]: args = 'a', 'b', 'c'

In [3]: kwargs = {}

In [4]: def g(x,y,opt_key = None):
   ...:   return something
   ...:
   ...: def h(z,opt_key = None):
   ...:   return something_else
   ...:

In [5]: g_signature = inspect.signature(g)

In [6]: g_signature.bind(*args, **kwargs)
Out[6]: <BoundArguments (x='a', y='b', opt_key='c')>

Note, this BoundArguments object acts as a mapping:

In [7]: bound_arguments = g_signature.bind(*args, **kwargs)

In [8]: bound_arguments.arguments['opt_key']
Out[8]: 'c'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...