[Python-Dev] defmacro (was: Anonymous blocks)
Samuele Pedroni
pedronis at strakt.com
Tue Apr 26 00:45:43 CEST 2005
Robert Brewer wrote:
> Shane Hathaway wrote:
>
>>Robert Brewer wrote:
>>
>>>So currently, all subclasses just override __set__, which leads to a
>>>*lot* of duplication of code. If I could write the base
>>
>>class' __set__
>>
>>>to call "macros" like this:
>>>
>>> def __set__(self, unit, value):
>>> self.begin()
>>> if self.coerce:
>>> value = self.coerce(unit, value)
>>> oldvalue = unit._properties[self.key]
>>> if oldvalue != value:
>>> self.pre()
>>> unit._properties[self.key] = value
>>> self.post()
>>> self.end()
>>>
>>> defmacro begin:
>>> pass
>>>
>>> defmacro pre:
>>> pass
>>>
>>> defmacro post:
>>> pass
>>>
>>> defmacro end:
>>> pass
>>
>>Here is a way to write that using anonymous blocks:
>>
>> def __set__(self, unit, value):
>> with self.setting(unit, value):
>> if self.coerce:
>> value = self.coerce(unit, value)
>> oldvalue = unit._properties[self.key]
>> if oldvalue != value:
>> with self.changing(oldvalue, value):
>> unit._properties[self.key] = value
>>
>> def setting(self, unit, value):
>> # begin code goes here
>> yield None
>> # end code goes here
>>
>> def changing(self, oldvalue, newvalue):
>> # pre code goes here
>> yield None
>> # post code goes here
>>
>
> ...
>
>>Which do you prefer? I like fewer methods. ;-)
>
>
> I still prefer more methods, because my actual use-cases are more
> complicated. Your solution would work for the specific case I gave, but
> try factoring in:
>
> * A subclass which needs to share locals between begin and post, instead
> of pre and post.
>
> or
>
> * A set of 10 subclasses which need the same begin() but different end()
> code.
>
> Yielding seems both too restrictive and too inside-out to be readable,
> IMO.
>
>
it seems what you are asking for are functions that are evaluated in
namespace of the caller:
- this seems fragile, the only safe wat to implement 'begin' etc is to
exactly know what goes on in __set__ and what names are used there
- if you throw in deferred evaluation for exprs or suites passed in
as arguments and even without considering that, it seems pretty horrid
implementation-wise
Notice that even in Common Lisp you cannot really do this, you could
define a macro that produce a definition for __set__ and takes fragments
corresponding to begin ... etc
More information about the Python-Dev
mailing list