Anonymous class members

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Carlos Ribeiro

    #1

    Anonymous class members

    I thought about this problem over the weekend, after long hours of
    hacking some metaclasses to allow me to express some real case data
    structures as Python classes. I think that this is something with
    potential to be useful, but I would like to hear more opinions first.
    If this is deemed to be useful, I *may* try to write a PEP for it.
    This is not a promise or even a proposal, at this point.

    Broadly generalizing, classes in Python have named members stored in
    their pravate __dict__. For normal Python code, this is not an issue.
    However, some types of data structures do not need named members. For
    example, this is a declaration of a simple web page template that
    (ab)uses a Python class declaration:

    class WebPage:
    __metaclass__ = WebPageTemplate

    class MyPage(WebPage) :
    class header(HtmlHead er):
    title = 'My WebPage'
    class body(HtmlBody)
    H1('Anonymous class members' )
    P('This is an example of anonymous class members')

    In the example above, MyPage.body contains two anonymous class
    members. There are good reasons not to name them. In the case of long
    templates, names are arbitrary, and most of the time are not ever
    used.

    I'm definining anonymous members as anything that is not a def, a
    nested class, or a value that wasn't assigned or bound to name.
    Everytime an expression is evaluated in the body of a class, and it's
    result is *not* bound to a name, then it's value is stored the magic
    _anon__ tuple. Methods or functions that return no value store None as
    their return value. Named attributes don't store anything.

    As a matter of fact, Python already has a related concept in the
    implicit naming of the __doc__ docstring. It may or not pose a problem
    for this generalization. That's my basic proposal:

    class MyClass:
    """the first anonymous member is the doc string"""
    """the second anonymous member is __anon__[0]"""
    1.5 # __anon__[1] = 1.5

    The docstring would be a special case -- if the first anonymous value
    is a string, and iif it's the first statement, then it's stored as the
    __doc__ docstring. It could (or not) be copied also at __anon__[0].
    I'm not sure about it.

    Some ideas and alternatives still unexplored are:

    1) store the __anon__ members in the reverse order (the last value is
    always at __anon__0;

    2) in the case of loops, then anon members would just be stored as generated.

    3) instead of the anonymous members, provide the class with an
    augmented dict that can store everything that is declared inside the
    class: multiple definitions of the same name, anonymous members, etc.
    The mapping interface would retrieve only the named values, but an
    iterator would be provided to retrieve all members, named and
    anonymous, in the order they were declared. (** this is a general
    solution for a wider class of applications **)

    4) provide the __anon__ feature only if the metaclass creates it with
    a __anon__(cls) factory method. By default, *no anonymous members
    would be stored*, but if the metaclass provides a __anon__ structure,
    then it's used, and passed to new as an extra keyword argument
    (metaclass.__ne w__(cls, name, bases, dct, anon=None)).


    Another alternative: augmenting the metaclass interface
    ------------------------------------------------------------------------

    Beware: if up to this point I was in true brainstorm mode, now I'm in
    a brain-hurricane-season-in-Florida mode. Be warned :-)

    One alternative is to change the metaclass interface, in such a way
    that it has an opportunity to catch all statements executed in the
    class declaration *before* __new__ is called. A new metaclass method
    (lets us call it __store__) and a generator interface to the class
    definition could be provided. It would work like this:

    1) Immediately upon the class declaration, Python knows what metaclass
    it has to call. Either the class inherited a metaclass from an
    ancestor, or __metaclass__ member is defined in the first line of the
    class.

    2) Python's internals check the metaclass for the __store__ function.
    If it exists, it's called with the following parameters:

    __metaclass__._ _store__(cls, name, bases, class_generator )

    3) __store__ retrieves definitions from the class_generator as tuples
    of the form:

    (name, value)

    ....where name is None for anonymous class members. At this point, the
    metaclass can do whatever it pleases. It can change names, discard
    values, or insert calculated values of its own.

    4) __store__ returns the dict that will be passed to __new__. This
    dict can be an augmented version that stores multiple definitions for
    the same name, or anonymous values, or whatever is needed for the
    particular class..



    --
    Carlos Ribeiro
    Consultoria em Projetos
    blog: http://rascunhosrotos.blogspot.com
    blog: http://pythonnotes.blogspot.com
    mail: carribeiro@gmai l.com
    mail: carribeiro@yaho o.com
Working...