I would like to take string argument for class BalancedTrinary intializer, but the string type of argument is processed before it enters the init function. I guess I must override any class method which deals with those for int/long?

def val(number_sequence, base):
    """ produce integer value of number_sequence as base number """
    print number_sequence
    return sum(int(n) * base ** p for p, n in enumerate(reversed(number_sequence)))

def balanced_ternary_value(number):
    """ produce integer value of balanced ternary number """
    #print 'balanced_ternary_value', number, type(number)
    return val([(-1 if c == '-' else (1 if c == '+' else 0))
                for c in str(number)], 3)

def make_balanced(n):
    n = int(n)
    if not n:
        return '0'
    rest, this = divmod(n, 3)
    if this < 2:
        return (make_balanced(rest) if rest else '') + ('0+'[this]) 
        rest = (n+1) // 3
        return (make_balanced(rest) if rest else '') + '-'

class BalancedTernary(long):
    def __init__(self, n):
                      if isinstance(n, str) else n)

    def __repr__(self):
        return make_balanced(self)

    __str__ = __repr__

if __name__  == '__main__':
    print('%10s %10s' % ('dec', 'balanced ternary'))
    for t in range(-27,+28):
        print('%10s %10s' % (t, BalancedTernary(t)))

    print balanced_ternary_value('++-0+')
    print BalancedTernary('++-0+')


Traceback (most recent call last):
  File "I:\test\balanced.py", line 40, in <module>
    print BalancedTernary('++-0+')
ValueError: invalid literal for long() with base 10: '++-0+'

Edited 4 Years Ago by pyTony

This is a typical use case for the __new__() method:

class BalancedTernary(long):
    def __new__(cls, n):
        instance = long.__new__(cls,
            balanced_ternary_value(n) if isinstance(n, str) else n)
        return instance

    def __repr__(self):
        return make_balanced(self)

    __str__ = __repr__

Your code seems to work now.

Thanks for __new__ teaching!
This question has already been answered. Start a new discussion instead.