How do I do this? (eval() on the left hand side)

Bengt Richter bokr at oz.net
Thu Dec 9 18:20:16 CET 2004


On Tue, 07 Dec 2004 21:12:24 GMT, "It's me" <itsme at yahoo.com> wrote:

>
>"Caleb Hattingh" <caleb1 at telkomsa.net> wrote in message
>news:opsin754im1js0xs at news.telkomsa.net...
>> Hi It's me
>>
>> >
>> >     a = 3
>> >     y = "a"
>> >     print eval(y)
>> >
>>
>> To get 'a' to be 4 here, you would say
>>
>> a = 4
>>
>
>Obviously but that's not what I wish to do.
>
>> I am not sure why you would want to do otherwise?  Perhaps you could
>> sketch out a little more about what you are trying to do?  That would help
>> a lot.  Are you aiming for something like pointer emulation with simple
>> datatypes?
>>
>
>In REXX, for instance, one can do a:
>
>    interpret y' = 4'
>
>Since y contains a, then the above statement amongs to:
>
>    a = 4
>
>There are many situations where this is useful.   For instance, you might be
>getting an input which is a string representing the name of a variable and
>you wish to evaluate the expression (like a calculator application, for
>instance).
>
If you want to make a calculator, why not define a calculator class that
behaves the way you like, giving it methods for interaction according to any
syntax you like?

What would you like to be able to type for your calculator to interpret?
assignment statements and expressions? There is a difference between the
statements your calculator interprets and the statements you use to implement
your calculator, unless you are hoping just to pass input through for Python
to interpret (which will be risky if you don't control what's entered!).

But, to pursue your REXX example a bit, the question IMO is how important the
spelling is to you vs the functionality. Python lets you create custom objects
that behave pretty much any way you like. You can (ab)use the way python compiles
various operators operating on or with instances of your custom objects so you can
spell things in various ways, e.g., instead of
    a = 3
    y = "a"
    print eval(y)

you could have a magic class instance o and write
    o.a = 3
    o.y = "a"
    print o().y

and instead of 

    interpret y' = 4'

write
    o().y = 4 

Let's try it (untested beyond what you see here ;-)

 >>> class Magic(object):
 ...     def __call__(self):
 ...         return DerefName(self)
 ...
 >>> class DerefName(object):
 ...     def __init__(self, wrapped):
 ...         object.__setattr__(self, 'wrapped', wrapped)
 ...     def __getattr__(self, name):
 ...         wrapped = object.__getattribute__(self, 'wrapped')
 ...         return getattr(wrapped, getattr(wrapped, name))
 ...     def __setattr__(self, name, value):
 ...         wrapped = object.__getattribute__(self, 'wrapped')
 ...         setattr(wrapped, getattr(wrapped, name), value)
 ...
 >>> o = Magic()
 >>> o.a = 3
 >>> o.y = "a"
 >>> print o().y
 3
 >>> o().y = 4
 >>> print o().y
 4
 >>> o.y
 'a'
 >>> o.a
 4
 >>> o().z
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 6, in __getattr__
 AttributeError: 'Magic' object has no attribute 'z'
 >>> o.z = "y"
 >>> o().z
 'a'
 >>> o.z
 'y'

Anyway, getattr/setattr functionality provides the primal cauldron for python magic,
if you want to cook something up, and incantations usually involve prefixing the name of
a magic instance to your spell(ing)s ;-) Add descriptors for extra spice ...

Double, double, toil and trouble... oh, wait, that's for floating point ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list