is it possible to access the python function object attributes from within the function scope?
e.g. let\'s have
def f():
return
Another way to accomplish this is to define the function inside another function, and have the outer function return the inner one. Then the inner function can access itself via a closure. Here's a simple example:
def makeFunc():
def f():
return f._x
return f
Then:
>>> f = makeFunc()
>>> f._x = "foo"
>>> f()
'foo'
>>> g = f
>>> del f
>>> g()
'foo'
If there is only one method needed but you want a light-weight class with shared class state plus individual instance state, you might try the closure pattern like this:
# closure example of light weight object having class state,
# local state, and single method
# This is a singleton in the sense that there is a single class
# state (see Borg singleton pattern notebook)
# BUT combined with local state
# As long as only one method is needed, this one way to do it
# If a full class singleton object is needed with multiple
# methods, best look at one of the singleton patterns
def LW_Object_Factory(localState):
# class state - doesn't change
lwof_args = (1, 2, 3)
lwof_kwargs = {'a': 4, 'b': 5}
# local instance - function object - unique per
# instantiation sharing class state
def theObj(doc, x):
print doc, 'instance:'
print '\tinstance class state:\n\t\targs -', \
lwof_args, ' kwargs -', lwof_kwargs
print '\tinstance locals().items():'
for i in locals().items():
print '\t\t', i
print '\tinstance argument x:\n\t\t', '"{}"'.format(x)
print '\tinstance local state theObj.foo:\n\t\t',\
'"{}"'.format(theObj.foo)
print ''
# setting local state from argument
theObj.foo = localState
return(theObj)
lwo1 = LW_Object_Factory('foo in local state for first')
lwo2 = LW_Object_Factory('foo in local state for second')
# prove each instance is unique while sharing class state
print 'lwo1 {} distinct instance from lwo2\n'\
.format(id(lwo1) <> id(lwo2) and "IS" or "IS NOT")
# run them
lwo1('lwo1', 'argument lwo1')
lwo2('lwo2', 'argument lwo2')
As a workaround you could use a factory function to fix your scope:
def factory():
def inner():
print inner.x
return inner
>>> foo=factory()
>>> foo.x=11
>>> foo()
11
>>> bar = foo
>>> del foo
>>> bar()
11
You could just use a class to do this
>>> class F(object):
... def __call__(self, *args, **kw):
... return self._x
...
>>> f=F()
>>> f._x = "foo"
>>> f()
'foo'
>>> g=f
>>> del f
>>> g()
'foo'
Just define your function inside a closure:
def generate_f():
def f():
return f.x
return f
f = generate_f()
f.x = 314
g = f
del f
print g()
# => 314
If you want it to be totally independent of the function name, you need some frame magic. For example:
def f2():
import inspect
frame = inspect.currentframe()
fname = frame.f_code.co_name
fobj = frame.f_globals[fname]
print fobj._x
f2._x = 2
f2()