Python print and types selection

M

mark.seagoe

Python 2.5, PC.

I have a question about getting Python print to be able to recognize a
long type.


class bignumber(object):

def __init__(self, initval=0):
self.val = initval
#
def __int__(self):
print 'bignumber.__int__ returning a %s' % type(self.val)
return self.val
#
def __long__(self):
print 'bignumber.__long__ returning a %s' % type(self.val)
return long(self.val)

def str(self):
return '0x%016X' % self.val
#
print 'TEST 1'
dog = 0x123456789ABCDEF0
print 'type(dog) = %s' % type(dog)
print 'dog val = 0x%016X' % dog

print 'TEST 2'
cat = bignumber(0x55)
print 'cat val = 0x%016X' % cat
print 'type(cat) = %s' % type(cat)

print 'TEST 3'
bird = bignumber(dog)
print 'type(bird) = %s' % type(bird)
print 'bird val = 0x%016X' % long(bird)
print 'bird val = 0x%016X' % bird

When I run this, I get:

TEST 1
type(dog) = <type 'long'>
dog val = 0x123456789ABCDEF0
TEST 2
bignumber.__int__ returning a <type 'int'>
cat val = 0x0000000000000055
type(cat) = <class '__main__.bignumber'>
TEST 3
type(bird) = <class '__main__.bignumber'>
bignumber.__long__ returning a <type 'long'>
bird val = 0x123456789ABCDEF0
bignumber.__int__ returning a <type 'long'>
Traceback (most recent call last):
File "C:\PythonTesting\bignmber.py, line 32, in <module>
print 'bird val = 0x%016X' % bird
TypeError: int argument required

Python print recognizes the local constant "dog", but it goes and
fetches the __int__ type from my object-based class, even though it's
value is a long. Then Python print doesn't expect a long to come back
and bombs out. I don't want to force the main program to cast the
long value getting returned. I know Python print can print a long,
but how can I make it select the __long__ instead of the __int__ ?

Thanks.
 
M

mark.seagoe

What I mean is, is there a way to change the class so that print will
see it as a long, without having to cast it as one in the main
program.
 
G

Gabriel Genellina

Python 2.5, PC.

I have a question about getting Python print to be able to recognize a
long type.

[...]

print 'TEST 3'
bird = bignumber(dog)
print 'type(bird) = %s' % type(bird)
print 'bird val = 0x%016X' % long(bird)
print 'bird val = 0x%016X' % bird

When I run this, I get:
[...]
TEST 3
type(bird) = <class '__main__.bignumber'>
bignumber.__long__ returning a <type 'long'>
bird val = 0x123456789ABCDEF0
bignumber.__int__ returning a <type 'long'>
Traceback (most recent call last):
File "C:\PythonTesting\bignmber.py, line 32, in <module>
print 'bird val = 0x%016X' % bird
TypeError: int argument required

Python print recognizes the local constant "dog", but it goes and
fetches the __int__ type from my object-based class, even though it's
value is a long. Then Python print doesn't expect a long to come back
and bombs out. I don't want to force the main program to cast the
long value getting returned. I know Python print can print a long,
but how can I make it select the __long__ instead of the __int__ ?

This bug was corrected in version 2.6 - see
http://bugs.python.org/issue1742669
If you have to stay with 2.5 I'm afraid any solution would require to
modify your code:

-- put long() around those arguments
-- "%s" % format_hex(val) (where format_hex does the long conversion)
-- redefine __str__ and use %s
 
M

Miles

This bug was corrected in version 2.6 - see
http://bugs.python.org/issue1742669
If you have to stay with 2.5 I'm afraid any solution would require to modify
your code:

-- put long() around those arguments
-- "%s" % format_hex(val) (where format_hex does the long conversion)
-- redefine __str__ and use %s

Or make your class a subclass of long.

-Miles
 
M

mark.seagoe

Or make your class a subclass of long.

-Miles- Hide quoted text -

- Show quoted text -

Absolute genius. Wish I had thought of that. Thanks to both of you.
 
M

mark.seagoe

Or make your class a subclass of long.

-Miles- Hide quoted text -

- Show quoted text -

It appears that if I make the class a subclass of long...
class bignumber(long):
def __init__(self, initval):
self.val = initval

Then if I make a new class of subclass of bignumber...
class myclass(bignumber):
def __init__(self, another_custom_class)
bignumber.__init__(self, 0)
do some stuff with another_custom_class

When I try to use this, I get an error sort of like this:
"TypeError: long() argument must be a string or a number, not
[whatever type another_custom_class is]"

Would paste code here but it's pretty extensive, and hopefully this
conveys the idea. For me upgrading Python version is at this time not
an option, because I work for a very large company and they're all
using Python 2.5.3.

So then is it required that I stuff a long as the first arg of
myclass, or is there a way around this? I read another post and
followed advice to add the __new__() method, actually looking the same
as __init__(), but then it later bombs out when the main routine tries
to print from this line:
print 'dog val = 0x%016X' % dog
saying "TypeError: int argument required", which is worse than it was
originally.

I probably need some tutorial on internals of Python, huh?

Thanks!
 
M

mark.seagoe

...
It appears that if I make the class a subclass of long...
class bignumber(long):
    def __init__(self, initval):
        self.val = initval
Then if I make a new class of subclass of bignumber...
class myclass(bignumber):
    def __init__(self, another_custom_class)
        bignumber.__init__(self, 0)
        do some stuff with another_custom_class
When I try to use this, I get an error sort of like this:
"TypeError: long() argument must be a string or a number, not
[whatever type another_custom_class is]"

Remember that long is an immutable class (so you need to fiddle __new__,
not __init__).  So, do something a bit more like:

     class BigNumber(long):
         def __repr__(self):
             return '%s(%s)' % (type(self).__name__, self)

     class HugeNumber(BigNumber):
         def __new__(class_, something):
             return BigNumber.__new__(class_, something * 3)

  then you can do something like:
     print 'dog = %r = %016X' % (HugeNumber(123), HugeNumber(123))

Hope that helps.

--Scott David Daniels
(e-mail address removed)- Hide quoted text -

- Show quoted text -

Thanks, Scott.

I'm not sure what the "something * 3" does? Here is the printout:
dog = HugeNumber(369) = 0000000000000171
But I was able to put the concept into practice.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top