bin() 可以像 Python 2.6 中的 oct() 和 hex() 一样重载吗?
Posted
技术标签:
【中文标题】bin() 可以像 Python 2.6 中的 oct() 和 hex() 一样重载吗?【英文标题】:Can bin() be overloaded like oct() and hex() in Python 2.6? 【发布时间】:2010-11-03 09:06:39 【问题描述】:在 Python 2.6(及更早版本)中,hex()
和 oct()
内置函数可以通过定义 __hex__
和 __oct__
特殊函数在类中重载。但是,没有 __bin__
特殊函数用于重载 Python 2.6 的新 bin()
内置函数的行为。
我想知道有没有办法灵活重载bin()
,如果没有我想知道为什么接口不一致?
我知道可以使用__index__
特殊函数,但这并不灵活,因为它只能返回一个整数。我的特殊用例来自bitstring 模块,其中前导零位被认为是重要的:
>>> a = BitString(length=12) # Twelve zero bits
>>> hex(a)
'0x000'
>>> oct(a)
'0o0000'
>>> bin(a)
'0b0' <------ I want it to output '0b000000000000'
我怀疑没有办法做到这一点,但我认为问一下也无妨!
【问题讨论】:
【参考方案1】:正如您已经发现的那样,您不能覆盖bin()
,但听起来您不需要这样做。您只需要一个 0 填充的二进制值。不幸的是在python 2.5及之前的版本中,你不能使用“%b”来表示二进制,所以你不能使用“%”字符串格式化操作符来达到你想要的结果。
幸运的是,python 2.6 确实以新的str.format() 方法的形式提供了您想要的东西。我相信您正在寻找这种特殊的线路噪音:
>>> '0:010b'.format(19)
'0000010011'
这种迷你语言的语法在文档中的“format specification mini-language”下。为了节省您一些时间,我将解释我正在使用的字符串:
-
参数零(即
19
)应该被格式化,使用
一个神奇的“0
”表示我想要用 0 填充、右对齐的数字
10 位精度,单位为
二进制格式。
您可以使用此语法来实现各种创意版本的对齐和填充。
【讨论】:
谢谢,知道这很有用。虽然我已经设法以我想要的形式获得输出,但我无法让 bin 函数将其返回给我。您的 str.format 方法比我使用的方法要简洁得多! 另见***.com/questions/3258330/…【参考方案2】:我认为简短的回答是“不,bin()
不能像 oct()
和 hex()
那样被重载。”
至于为什么,答案肯定在Python 3.0,它使用__index__
重载hex()
、oct()
和bin()
,并且完全去掉了__oct__
和__hex__
的特殊函数。
所以 Python 2.6 bin()
看起来很像它实际上是 Python 3.0 的一个特性,它已经被向后移植,没有太多考虑它是以新的 Python 3 方式而不是旧的 Python 2 方式做事。我也猜想它不太可能得到修复,即使它被认为是一个错误。
【讨论】:
【参考方案3】:bin 函数从对象的__index__
函数接收它的值。所以对于一个对象,可以定义转换为二进制的值,但是不能定义字符串的格式。
【讨论】:
【参考方案4】:您可以通过使用您自己的实现覆盖/替换内置的 bin() 函数来实现与十六进制和八进制相同的行为,该实现试图在传递的对象上调用 bin 并回退到如果对象没有提供 bin,则使用标准 bin() 函数。但是,在显式优于隐式的基础上,将应用程序编码为依赖于自定义版本的 bin() 可能不是一个好主意,因此可能只是给函数起一个不同的名称,例如
def mybin(n):
try:
return n.__bin__()
except AttributeError:
return bin(n)
至于为什么界面不一致,我不确定。也许是因为 bin() 是最近添加的,所以有点疏忽?
【讨论】:
以上是关于bin() 可以像 Python 2.6 中的 oct() 和 hex() 一样重载吗?的主要内容,如果未能解决你的问题,请参考以下文章
python并发编程:异步IO(Asynchronous I/O)
将 python 2.7 timedelta.total_seconds() 转换为 python 2.6 中的等价物