overload builtin operator
Bengt Richter
bokr at oz.net
Fri Aug 26 17:21:19 EDT 2005
On Thu, 25 Aug 2005 16:12:20 +0200, Reinhold Birkenfeld <reinhold-birkenfeld-nospam at wolke7.net> 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
More information about the Python-list
mailing list