Newbie can't figure out documentation practices

Bengt Richter bokr at oz.net
Fri May 9 18:53:34 EDT 2003


On Fri, 09 May 2003 11:05:22 -0600, Fernando Perez <fperez528 at yahoo.com> wrote:

>sismex01 at hebmex.com wrote:
>
>>> The only other area where you're likely to cry a bit is proper string
>>> interpolation, which sucks in python.
>>>
>> 
>> Awww, c'mon, don't scare away the newbies!  Besides, it's
>> really a matter of perception; for me, Python's string
>> interpolation is excellent, specially after working
>> with shell and perl strings. Python's intrpolation feels
>> more first-world-like, more "formal", instead of perl's
>> and sh's.
>
>Ok, time for my yearly rant on interpolation ;)  Can anyone tell me how to
>do cleanly something like (using perl-like syntax to indicate my intent,
>this isn't real code):
>
>print """
>var x = $x
>var y = $y
>var self.z = $self.z
>fun x+y+self.z = $x+$y+$self.z
>var z from other object = $other.z
>z from self plus other = $self.z + $other.z
>"""  % ????
>
>I can't use locals() b/c it won't see the members of self and other. I can't
>update locals() with self/other.__dict__ because they'll clobber each
>other.
>
>In general the only solution I've been able to find is to make a bunch of
>local temporaries to hold all of my object's data plus assorted other stuff
>in locals() as non-dotted names.  That strikes me as ugly and unpythonic,
>but I've failed to find a better alternative.  I'd love to be enlightened.
>
>I vaguely recall some nice class-based trick I saw a while back, but I'd
>like a more 'standard' mechanism.  Ka-Ping Yee's Itpl class seems wonderful
>to me, but all attempts to push that have failed so far.  
>
>I've been told to write the above with tons of print statements (one per
>line) and even more quotemarks:
>
>print 'x=',x,'self.z=',self.z,...
>
>But I _hate_ that kind of output for anything longer than two or three
>lines.  It's nearly impossible to read smoothly something which is say 50
>lines of the above with many variables.
>
>

Here's something to get values from various dicts and optional attributes of objects:
You can use it more simply, but this illustrates a few issues:

====< valsources.py >================================================
class ValSources:
    def __init__(self, *valsources):
        self.valsources = valsources
    def __call__(self, *dicts):
        self.valsources += dicts
        return self
    def __getitem__(self, keystr):
        attrs = keystr.split('.')
        name, attrs = attrs[0], attrs[1:]
        for ns in self.valsources:
            if name in ns:
                obj = ns[name]
                break;
        else:
            return '<%s is undefined>'%`keystr`
        for attr in attrs:
            try:
                obj = getattr(obj, attr)
            except AttributeError:
                return '<%s is undefined>'%`keystr`
        return obj

# global test data
x = 111
class Other: pass
other = Other(); other.z = 444
other.deeper = Other()
other.deeper.z = 555

def test():
    nested = 'accessible from show, but note namespace'
    class C:
        z = 333 # class instance data via method local 'self' as self.z
        def show(self, valsources):
            y = 222 # (method) local data 
            print """
            var x = %(x)s
            var y = %(y)s
            var self.z = %(self.z)s
            fun x+y+self.z = %(x)s+%(y)s+%(self.z)s
            var z from other object = %(other.z)s
            z from self plus other = %(self.z)s + %(other.z)s
            nested = %(nested)s <-- added example
            other.deeper.z = %(other.deeper.z)s <-- another example
            """  % valsources(locals()) # to try method locals first
            
    c = C()
    c.show(ValSources(locals(), globals())) # note: locals here are of test
    
if __name__ == '__main__':
    test()
=====================================================================

when run:

[15:51] C:\pywk\stringInterp>valsources.py

            var x = 111
            var y = 222
            var self.z = 333
            fun x+y+self.z = 111+222+333
            var z from other object = 444
            z from self plus other = 333 + 444
            nested = accessible from show, but note namespace <-- added example
            other.deeper.z = 555 <-- another example

Simpler example:

 >>> from valsources import ValSources
 >>> x = 111
 >>> def test():
 ...     y = 222
 ...     print """
 ...     x = %(x)s
 ...     y = %(y)s
 ...     """ % ValSources(vars(),globals())
 ...
 >>> test() 

     x = 111
     y = 222

Or just

 >>> print 'x=%(x)s'%ValSources(globals())
 x=111

Which doesn't make much sense, since

 >>> print 'x=%(x)s'%globals()
 x=111

But for stuff with attributes

 >>> class X: pass
 ...
 >>> x=X()
 >>> x.y = 123
 >>> x.z = 'something'
 >>> print 'x.y=%(x.y)s, x.z=%(x.z)s' % globals()
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 KeyError: x.y

So this helps

 >>> print 'x.y=%(x.y)s, x.z=%(x.z)s' % ValSources(globals())
 x.y=123, x.z=something


Regards,
Bengt Richter




More information about the Python-list mailing list