If you want X, you know where to find it (was Re: do...until wisdom needed...)
Jeff Epler
jepler at inetnebr.com
Sat Apr 21 21:34:55 EDT 2001
On 18 Apr 2001 01:27:37 -0400, Douglas Alan
<nessus at mit.edu> wrote:
> Well, yes, you could use a procedural macro (hygienic, or otherwise)
> to convert Pascal code to Python, but it would be one really big hairy
> macro, and I don't think that be a good idea. More modestly, you
> might define two macros, "let" and "set" so that
>
> let x = 3
>
> gets translated into
>
> try:
> x
> raise VariableAlreadyBound("x")
> except NameError:
> x = 3
>
> and
>
> set x = 3
>
> gets tranlated into
>
> try:
> x
> x = 3
> except NameError:
> raise VariableNotBound("x")
This particular example can be done with very nearly the same syntax in
standard Python---a dot instead of whitespace between let/set and the
variable in question.
>>> import letset, __main__; letset.setup(__main__)
>>> let.x = 3
>>> x
3
>>> let.x = 4
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "getset.py", line 10, in __setattr__
raise VariableAlreadyBound(attr)
getset.VariableAlreadyBound: x
>>> set.y = 5
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "getset.py", line 20, in __setattr__
raise VariableNotBound(attr)
getset.VariableNotBound: y
>>> set.x = 6
>>> print x
6
(letset is also suitable for use in a class, though the syntax becomes a bit
odder:
>>> class C:
... def __init__(self, arg):
... letset.setup(self)
... self.let.x = arg
...
>>> y = C(4)
>>> y.x
4
let.self.x won't work for reasons that should be obvious after a moment's
thought)
In function context, 'set.x=...' provides a nice replacement for
'global x; x=...', I'm inclined to think.
Jeff Epler
jepler at inetnebr.com
#--- letset.py ----------------------------------------------------------
class VariableAlreadyBound(Exception): pass
class VariableNotBound(Exception): pass
class Let:
def __init__(self, namespace):
self.__dict__['_Let__n'] = namespace
def __setattr__(self, attr, val):
if hasattr(self.__n, attr):
raise VariableAlreadyBound(attr)
setattr(self.__n, attr, val)
class Set:
def __init__(self, namespace):
self.__dict__['_Set__n'] = namespace
def __setattr__(self, attr, val):
if not hasattr(self.__n, attr):
raise VariableNotBound(attr)
setattr(self.__n, attr, val)
def setup(namespace):
setattr(namespace, "let", Let(namespace))
setattr(namespace, "set", Set(namespace))
#------------------------------------------------------------------------
More information about the Python-list
mailing list