Skip to content

Instantly share code, notes, and snippets.

@lsloan
Last active February 4, 2017 11:46
Show Gist options
  • Save lsloan/00d2bd22e62d7061ed98500dd716f0a5 to your computer and use it in GitHub Desktop.
Save lsloan/00d2bd22e62d7061ed98500dd716f0a5 to your computer and use it in GitHub Desktop.
Find which arguments of a method have defaults and add them to kwargs if they're not None.
from __future__ import print_function
import inspect
import pprint
class MyClass(object):
def myFunc(self, arg1, arg2=None, arg3=None, *args, **kwargs):
# Find which arguments of this method have defaults and add them to kwargs if they're not None
# Problem: locals() doesn't tell us that arg2 was declared with a default
localVariables = locals()
print('locals:', localVariables)
# {'arg1': 'arg1', 'arg2': 'arg2', 'self': <__main__.MyClass object at...>, 'kwargs': {...}}
# Problem: inspect.getargspec() will tell which arguments were declared and how many have defaults,
# but it needs an object reference to this method (function), not just its name.
# print('getargspec:', inspect.getargspec(self.myFunc)) # works, but need to put name of this function
# print('getargspec:', inspect.getargspec('myFunc')) # TypeError: 'myFunc' is not a Python function
# Problem: getting the name of this method is not very difficult,
# but getting a reference to it is a little more work.
frame = inspect.currentframe()
thisMethodName = inspect.getframeinfo(frame).function
thisMethod = inspect.getmembers(self, lambda x: inspect.ismethod(x) and x.__name__ == thisMethodName)[0][1]
print('thisMethod:', thisMethod)
argspec = inspect.getargspec(thisMethod)
print('getargspec:', argspec)
defaultsArgs = argspec.args[-len(argspec.defaults):]
print('defaultsArgs:', defaultsArgs)
print('kwargs before:', pprint.pformat(kwargs))
print('filter:', filter(lambda (k, v): k in defaultsArgs and v is not None, localVariables.iteritems()))
# Update kwargs with dictionary comprehension...
# kwargs.update({k: v for (k, v) in localVariables.iteritems()
# if k in defaultsArgs and v is not None})
# or...
# Update kwargs with filter...
kwargs.update(filter(lambda (k, v): k in defaultsArgs and v is not None, localVariables.iteritems()))
print('kwargs after:', pprint.pformat(kwargs))
# TODO: Move this to a function that may be used in any other function (or methods, at least)
# In external function, locals will not be available, so it will need to be passed in or
# gotten from the frame.
if __name__ == '__main__':
myClass = MyClass()
myClass.myFunc('arg1', arg2='arg2', fubar='snafu', fu=None)
# print(inspect.getargspec(MyClass.myFunc))
# print(inspect.getargspec(myClass.myFunc))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment