Attribute access by hacking decorators

Michele Simionato michele.simionato at gmail.com
Fri Oct 29 05:34:54 EDT 2004


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



More information about the Python-list mailing list