On Thu, 25 Aug 2005 16:12:20 +0200, Reinhold Birkenfeld <[EMAIL PROTECTED]> 
wrote:

>Shaun wrote:
>> Hi,
>> 
>> I'm trying to overload the divide operator in python for basic arithmetic.
>> eg. 10/2 ... no classes involved.
>> 
>> I am attempting to redefine operator.__div__ as follows:
>> 
>>      # my divide function
>>      def safediv(a,b):
>>          return ...
>> 
>>      # reassign buildin __div__
>>      import operator
>>      operator.__div__ = safediv
>> 
>> The operator.__dict__ seems to be updated OK but the '/' operator still  
>> calls buildin __div__
>
>It won't work that way. You cannot globally modify the behaviour of an 
>operator,
>but you can customize how an operator works for your type.
>
>Consider:
>
>class safeint(int):
>    def __div__(self, other):
>        return safediv(self, other)
>
>safeint(10)/2
>
You are right that you cannot globally modify the behaviour of an operator in 
the
sense the OP seems to be envisioning, but with some trouble I think it would be 
possible
to interfere with the translation of '<numerator-term>/<denominator-term>' to 
become
'safediv(<numerator-term>, <denominator-term>)' by transforming the AST during 
a custom
import process, such that wherever a Div node is found, a CallFunc node is 
substituted. E.g.,

for a node like

    Div((Name('numerator'), Name('denominator')))

substitute another node like

    CallFunc(Name('safediv'), [Name('numerator'), Name('denominator')], None, 
None)

where the Name('numerator') and Name('denominator') in the latter are actually
the Div node's .left and .right, so as to operate on the same args (which can
be abitrary expression-representing subtrees).

Of course, you probably also want to replace

    AugAssign(Name('a'), '/=', Name('b'))

with

    Assign([AssName('a', 'OP_ASSIGN')], CallFunc(Name('safediv'), [Name('a'), 
Name('b')], None, None))

Unfortunately, the AST tree does not seem to be designed to be edited easily wrt
_replacing_ nodes found by walking via flattened lists vs. just _using_ them in 
order.

I think I can create special walker that can do replacements of nodes found 
anywhere, and
calling node-type-specific or default supplied callbacks to supply replacements 
for original nodes
passed to them, but this will require a number of specialized visitors etc., so 
I will have to get back
to this later. But at least the OP and you nudged me into thinking about AST 
rewriting again ;-)
(also affects my @@sourcedeco ideas ;-)

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to