0

Let's say we have the following class:

class Foo:
    def __init__(self):
        self.bar = "12"

    def __str__(self):
        return self.bar
    
    def __int__(self, *args, **kwargs):
        print("inside __int__")
        return int(self.bar, *args, **kwargs)


a = Foo()
print(int(a))
# -> inside __int__
# -> 12

The result of printing this is as you would expect. However if we try:

print(int(a, 10))   # or any other valid base instead of 10

the following exception is raised:

TypeError: int() can't convert non-string with explicit base

Also, inside __int__ is not printed meaning that a.__int__ is not called. Is there any special method which would allow specifying a base in the int() call or do I just have to live with this behavior?

Even more interesting (and more in the direction of what I want to do) is the following:

class Foo(str):   # subclass of str and excepts argument in constructor
    def __init__(self, bar):
        self.bar = bar

    def __int__(self, *args, **kwargs):
        return int(self.bar, *args, **kwargs)


a = Foo("12")
print(int(a), int(a, 10))
# -> 12 12
# Actually works

a.bar = "34"
print(int(a), int(a, 10))
# -> 34 12
# what?

My assumption on this one is that int(num, base) uses num.__getnewargs__(). Either way, is there any way to get around these examples?

0

1 Answer 1

1

This behaviour is specifically called out in the documentation of int:

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in radix base.

The __int__ "magic method" (or __index__, __trunc__ which are used as fallbacks) is only invoked when the base argument is not provided.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I've read the documentation on this. So in other words, it's up to me to say int(a.bar, some_base) instead, right?
@Mr_HxID that could be one way to handle it, yes. Or e.g. if the base was a property of the instance the __int__ implementation could return(self.bar, self.base) and be used with the single-arg int.
Ok, I'll probably do something similar to this then. Still, I find it kind of silly of python to place such a restriction on the multi-arg int. But thanks for your quick reply.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.