1

I have a piece of code where I pull a function out of a dictionary, then add an object attribute to it. However I am having some problems accessing it from within the function, presumably due to the namespace.

aFunction = FunctionsDictionary[key]
aFunction.someObject = someObject
aFunction()

def aFunction():
    someObject.doSomething()

Gives NameError global name 'someObject' is not defined.

If I do a dir(aFunction) after I set the attribute I can see it, however a dir() from within the function does not show the attribute.

Although I can likely change the code to have the function accept the object as an argument, how do I refer to these attributes set on the 'instance' of the function?

Here is another example:

def myFunc():
    print coolAttr

func = myFunc
func.coolAttr = "Cool Attribute"
func()
NameError: global name 'coolAttr' not defined
taylormade201
  • 696
  • 2
  • 9
  • 25

1 Answers1

1

It doesn't seem like there's a (good) way to get a reference to the currently running function in Python; see Is there a generic way for a function to reference itself? and Python code to get current function into a variable? . In the case that all your functions are defined with names using def, you could just refer to the function by its name (e.g. aFunction in your example) to get its properties within the function body.

A bigger problem is that this may not have the effect you want... Functions are passed by reference in python, so if aFunction appears multiple times in the dict, there's still going to be only one copy of the function object. So if you set the property on multiple values of the dict, all of which happen to point to the same function, you'll only end up storing the last value of the property... Hard to know without more detail if that's what you need.

The best answer is probably to rewrite your code so the relevant value is passed as an argument.

Community
  • 1
  • 1
caseygrun
  • 2,019
  • 1
  • 15
  • 21
  • In general, it does not seem like you can add an attribute to a function reference at runtime (ie. outside of a decorator applied to the function definition). If I print the function instance after I assign the attribute to it, and then print self from within the function, they are not the same object (different memory addresses). I find this pretty confusing. I make an instance of the function from the dictionary, modify it, but when its run, its not the same object.? – taylormade201 Oct 01 '14 at 16:22
  • Within the body of a random function, `self` does _not_ refer to the currently-executing function. `self` is only defined when it's given explicitly as the first argument of a class method; it's not a keyword. See e.g. http://stackoverflow.com/a/2709832/4091874 and https://docs.python.org/2/tutorial/classes.html#random-remarks . – caseygrun Oct 01 '14 at 17:39
  • Sorry, in my comment, I wrote a decorator which bind the function: `def bind(func): return func.__get__(func,type(func))` – taylormade201 Oct 01 '14 at 17:53