Here is a hack to implement attribute access (say for a Web framework)
the way I always wanted it to be. I say "hack" since it uses sys._getframe
and it sets the locals of a class, which is not recommended. Still, it seems
to work. I post the recipe here since since I would like to know if
1. it really works;
2. if yes, is there a chance that it will not work in future versions of Python;
3. will it work under Jython?
Even if it turns out it does not work, still I like the feeling of it ;-)
Here is the decorator which builds the list of the public methods in the
actual scope (it may be the module level scope or the class level scope):
import sys
def public(f):
loc = sys._getframe(1).f_locals
if not "__public__" in loc:
loc["__public__"] = [f]
else:
loc["__public__"].append(f)
return f
Here is the usage for global functions:
@public
def g_a():
pass
@public
def g_b():
pass
print __public__ # [g_a, g_b]
Here is the usage for methods:
class D(object):
@public
def m_a(self):
pass
@public
def m_b(self):
pass
print __public__ # [m_a, m_b]
It seems to work for nested classes too:
class Outer(object):
@public
def m_a(self):
pass
@public
def m_b(self):
pass
class Inner(object):
@public
def i_a(self):
pass
@public
def i_b(self):
pass
print "inner",__public__ #[i_a, i_b]
print "outer",__public__ #[m_a, m_b]
Of course, it does not work at the function scope, as in this example:
def container():
@public
def i_a(self):
pass
@public
def i_b(self):
pass
print "container", __public__ # [g_a, g_b] and not [i_a, i_b]
container()
However, I do not regard this as a problem, since I only want to define
public/private functions/methods at the module and class level, not at the
function level. In my experiments settings the locals at the class scope works,
but I wonder how reliable is this, wrt to future versions of Python or alternative
implementations.
Hacking-decorators-ly yours,
Michele Simionato