In general, you cannot derive a name from a value (there can be no name, there can be several, etc.); when you call your hypothetical makedict(name) , value name is what makedict gets, so (again, in the general case) it cannot distinguish which name (if any) from. You could examine the namespaces of the callers to see if you just hit on a special occasion when the value allows you to output a name (for example, you get 23 ), and only one name in the namespaces of interest that happens to have a value of 23 ! ), but this is clearly a fragile and incorrect architecture. In addition, in your first example, the case is absolutely guaranteed that the special case will not be - the value in name will be exactly the same as in foo or baz , so 100% are sure that the name for this value will be hopelessly ambiguous.
You can use a completely different approach, for example calling makedict('name type', locals()) (passing locals() can clearly be eliminated with the help of dark and deep magic of introspection, but this is not the hardest choice at all) - go to names ( and namespaces, I suggest!) and makedict output the values , which, obviously, is a much stronger sentence (since each name has exactly one meaning, but not vice versa). I.e:.
def makedict(names, *namespaces): d = {} for n in names.split(): for ns in namespaces: if n in ns: d[n] = ns[n] break else: d[n] = None
If you are interested in digging up namespaces by introspection, rather than just specifying them as callers, look at inspect.getouterframes - but I suggest you reconsider.
The second problem you are raising is completely different (although you could use the inspect functions again to understand the caller name or the function’s own name - what a peculiar idea!). What is common in two cases is that you use an extremely powerful and dangerous mechanism to carry out work that can be done much easier (easier to ensure correctness, easier to debug any problems, easier to test, etc.) - - far from that so that decorators are "redundant", they are far simpler and clearer than your introspection. If you have zillion methods all forms:
def item_blah(self, item): dispatch("blah", item)
The easiest way to create them:
class Item(object): pass def _makedispcall(n): def item_whatever(self, item): dispatch(n, item) item_whatever.__name__ = 'item_' + n return item_whatever for n in 'create delete blah but wait theres more'.split(): setattr(Item, 'item_' + n, _makedispcall(n))
Avoiding repetition is a great idea, but runtime introspection is usually not the best way to implement this idea, and Python offers many alternative ways for such an implementation.