You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python自定义对象通过int()指定进制转整数的问题咨询

Python int() 转换的特殊行为与解决方案

一、自定义非字符串类的int带进制调用问题

先看你给出的代码示例:

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))  # 正常调用__int__,输出12
print(int(a, 10))  # 抛出TypeError,且未触发__int__

原因解析

Python内置int()函数的逻辑是:只有当第一个参数是字符串、字节串或字节数组类型时,才会解析指定进制。对于其他自定义对象,无论是否实现__int__方法,只要传入base参数,会直接抛出TypeError,根本不会触发__int__调用。

另外__int__方法的设计本身只支持无参数转换,Python调用它时不会传递任何额外参数,你定义时加的*args实际不会被用到。

解决方案

由于内置int()的逻辑无法修改,有两种可行思路:

  1. 自定义转换方法:在类中实现专门的进制转换方法
class Foo:
    def __init__(self):
        self.bar = "12"

    def __str__(self):
        return self.bar
    
    def to_int(self, base=10):
        print("inside to_int")
        return int(self.bar, base)

a = Foo()
print(a.to_int())       # -> inside to_int 12
print(a.to_int(16))     # -> inside to_int 18
  1. 模拟字符串行为:利用__str__的返回值,显式转换为字符串后调用int()
print(int(str(a), 10))  # 输出12,基于__str__的返回值解析进制

二、继承str类的int行为差异问题

再看你给出的继承str的类示例:

class Foo(str):
    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
a.bar = "34"
print(int(a), int(a, 10))  # -> 34 12

原因解析

str是不可变类型,实例创建时的字符串内容会被固化,你在__init__中添加的self.bar只是额外属性,和str实例本身的内容无关:

  • 调用int(a)(无base参数)时,Python会优先调用自定义的__int__方法,返回int(self.bar)的值;
  • 调用int(a, 10)(带base参数)时,Python会把a当成普通str处理,直接解析str实例本身的初始内容(创建时的"12"),完全不会触发__int__方法,所以修改self.bar为"34"后结果仍为12。

你的猜测正确:int(num, base)处理str子类时,会调用num.__getnewargs__()获取原始字符串内容,默认情况下该方法返回的是str实例自身的固化内容。

解决方案

重写__getnewargs__方法,让它返回你需要的self.bar,这样int(a, base)就会用self.bar的值解析进制:

class Foo(str):
    def __init__(self, bar):
        self.bar = bar

    def __int__(self, *args, **kwargs):
        return int(self.bar, *args, **kwargs)
    
    def __getnewargs__(self):
        # 返回用于解析进制的目标字符串
        return (self.bar,)

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

内容的提问来源于stack exchange,提问作者Mr_HxID

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:57:12