python-2.1 function attributes

Rainer Deyke root at rainerdeyke.com
Fri Jan 26 11:47:30 EST 2001


"Carel Fellinger" <cfelling at iae.nl> wrote in message
news:94s180$360$1 at animus.fel.iae.nl...
> "Tony J Ibbs (Tibs)" <tony at lsl.co.uk> wrote:
> >  def f(long_name, even_longer_name, still_longer_name) with \
> >          (publish=1, secure=0, grammar=f_grammar):
> >      """and here is the doc string."""
> >      print "bobbins"
>
> Can we use this second parameter list for closures as well?  Moreover,
> I most definitely would expect to be able to refer to publish etc within
> the function body without having to qualify it with the funtion name.
> And are assignments to those function attributes allowed within the
> function body?

In general, the idea of function attributes seems pretty dumb to me, since
the decorator pattern already allows you to do this:

class Decorator:
  def __init__(self, decorated):
    self.__decorated = decorated
  def __getattr__(self, name):
    return getattr(self.__decorated, name)
  def __call__(self, *args, **kwargs):
    self.__decorated(*args, **kwargs)
  # Override other operators too.

class AttributeDecorator(Decorator):
  def __init__(self, decorated, **attributes):
    self.__dict__.update(attributes)
    Decorator.__init__(self, decorated)

def f():
  pass

f = AttributeDecorator(f, publish=1, secure=0)


However, if these function attributes also act as "static" variables (in the
C sense), the proposal becomes interesting.  It is still redundant (since a
singleton with __call__ can do the same thing), but it could be convenient.

Simply adding the function attribute dictionary into the name search order
between local and global is one possibility.  The new keyword 'static' could
be used, analogous to 'global':

def f():
  static eggs
  eggs = spam

f.spam = 'Eggs and spam'
f()
print f.eggs

However, this would introduce a significant performance penality when
accessing names in the global namespace.  The obvious alternative is to
refer to the function by name:

def f():
  f.eggs = f.spam

This is prone to error where the name of f changes, and requires two lookups
per access, which is slow.


One somewhat radical approach would be to introduce a new keyword which acts
as a variable isn't really one and produces different bytecode, analogous to
C++'s 'this':

def f():
  __func__.eggs = __func__.spam

g = f
f.spam = 'spam and spam, with a side order of spam'
del f
g() # Still works


This '__func__' could also be used for a variety of other purposes.


--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games           -           http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor





More information about the Python-list mailing list