This recipe is based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/157572.
Calling parameters() inside a function will return that function's parameters as a dictionary. The dictionary does not include varargs, since *varargs items do not have a "name" that can be used as a key. However, *varkw is added to the dictionary, as an update.
There are three optional parameters that can be used to filter the information returned.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | def parameters(only=None, exclude=None, ignore='self'):
"""Returns a dictionary of the calling functions
parameter names and values.
The optional arguments can be used to filter the result:
only use this to only return parameters
from this list of names.
exclude use this to return every parameter
*except* those included in this list
of names.
ignore use this inside methods to ignore
the calling object's name. For
convenience, it ignores 'self'
by default.
"""
import inspect
args, varargs, varkw, defaults = \
inspect.getargvalues(inspect.stack()[1][0])
if only is None:
only = args[:]
if varkw:
only.extend(defaults[varkw].keys())
defaults.update(defaults[varkw])
if exclude is None:
exclude = []
exclude.append(ignore)
return dict([(attrname, defaults[attrname])
for attrname in only if attrname not in exclude])
|
parameters() has several applications, including debugging and introspection. The calling functions parameters _can_ be found using vars() or locals(), so long as no-assignments-occur in the function body before the attempt. parameters() doesn't suffer from this restriction. The parameters can also be accessed via inspection (which is how parameters() works), parameters() just simplifies this while providing extra filtering capabilities.
A possible use case:
<pre> def setattrs(obj, dictionary): obj.__dict__.update(dictionary)
class C: def __init__(self, a, b, c=3, **kwargs): setattrs(self, parameters())
def exclude_ab(self, a, b, c, d):
e = "e"
# locals|vars now contains 'e', parameters doesn't
setattrs(self, parameters(exclude=['a', 'b']))
def only_ab(self, a, b, c, d):
setattrs(self, parameters(['a', 'b']))
c = C(1,2,d=4) print "c.__dict__ =", c.__dict__ c.exclude_ab(10,20,30,40) print "c.__dict__ =", c.__dict__ c.only_ab(100,200,300,400) print "c.__dict__ =", c.__dict__ </pre>
A more magical version. # based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/157572
def __update__(include=[], exclude=[]):
useage
class c:
I think the name __update__ works here for two reasons:
The leading and trailing double underscores let users know that there's something special happening, and
what this method is doing is updating the dictionary of an instance with another dictionary made up of key/value pairs from __init__'s parameter list, i.e., something like this is going on:
self.__dict__.update(initparamsdict)
So, since what we're doing is updating a dictionary, in a special way, and the method to do that is called 'update', it seems like '__update__' would be a reasonable name. Other naming suggestions include 'selfupdate()' or 'self_set()' [Alex Martelli - Python Cookbook p.106].
Sometimes you could just use vars(). Sometimes, when you want to be quick and dirty, and when you're not using arguments or *keywords, you can use the built in vars(), instead of params():
class c:
You just have to use it before you bind any other variables inside __init__(), and you need to be aware that each of your instances will have an attribute 'self' that is bound to that instance. e.g.
<__main__.c instance at 0x014F9100\>
<__main__.c instance at 0x014F9100\>
It's up to you.
nevermind. Now that I've had time to think about it, I don't care for __update__ (too magical)