【问题标题】:Is there an easy way of using binary numbers in Python?有没有在 Python 中使用二进制数的简单方法?
【发布时间】:2018-08-25 04:58:16
【问题描述】:

我必须使用二进制格式的数字,我想知道是否有一种简单易用的内置方式来使用它们。我知道bytearray,但它适用于字节类型,而且绝对不直观(至少对我而言)。

那么,有什么方法可以轻松处理二进制数(将它们分配给变量、执行位运算、转换为 ASCII 等)?如果不是内置的,至少是一个不错且易于理解的模块。

以防我问的不够清楚,这里有一个例子,我认为处理二进制文件的好方法是:

    bin_num1 = Binary('100')
    bin_num2 = Binary(0)

    print(bin_num1.and(bin_num2))    # Prints 000

我使用的是 Python 3.6,但任何版本的任何解决方案都可以胜任。

编辑 1:

正如 cmets 中所指出的,0bXXX 可以从二进制文件中获取 type int,就像 bin() 会做相反的事情一样。尽管如此,这仍适用于整数,返回的结果将是一个整数,并且字符转换(例如bin('a'))将是一个错误并且需要进一步的转换(从 str 到 int,然后再到二进制)。

【问题讨论】:

  • Binary numbers in Python的可能重复
  • 像这样:0b0 & 0b100?
  • 是的,你们都说得对。实际上,答案可能是两者的结合。 “0b0 & 0b100”之类的操作将返回一个 int 类型,可以使用 bin( ) 将其转换为二进制。我将等待,看看是否有人提出了一个可以完成工作并返回二进制类型的答案。

标签: python python-3.x binary


【解决方案1】:

将二进制数分配给变量:您可以使用整数变量来保存二进制值。它们可以使用 0b 前缀从二进制表示中创建。

x = 0b110  # assigns the integer 6

执行位操作:位操作&),|),^(xor), ~ (not) 可用于整数并执行相应的二元运算。

x = 0b110
y = 0b011
z = x & y  # assigns the integer 0b010 (2)

将它们转换为 ASCII: 要将数字转换为 ASCII,您可以使用 chr

x = 0b1100001  # assigns 97
print(chr(x))  # prints 'a'

从 ASCII 转换:如果您使用整数表示二进制值,您可以使用ord 转换 ASCII 值。

s = 'a'
x = ord(a)  # assigns the integer 0b1100001 (97)

以二进制形式打印整数:可以在字符串"{0:b}"上使用字符串格式方法以二进制形式打印整数。

x = 0b1100001
s = "{0:b}".format(x)
print(s)  # prints '1100001'

如果您不介意0b 前缀,您也可以使用bin

x = 0b1100001
s = bin(x)
print(s)  # prints '0b1100001'

从二进制字符串中读取整数:int 函数允许您指定解析字符串时使用的基数。

x = int("1100001", 2)  # assigns the integer 0b1100001 (97)

【讨论】:

    【解决方案2】:

    您可以继承 int 并编写 __new__ 以将所需的输入解析为整数的二进制。我目前有 char 和一个支持零和一的字符串。

    您现在可以将其用作整数,并使用其所有方法进行二进制操作。如果您使用这些方法,它只会继续转换为整数。因此,您必须使用魔术函数(双下划线或 dunders)覆盖所有这些方法,以继续返回您的 Binary 类。这可能是重复的,但使用其他一些 python 魔法可以非常简洁。

    注意。我可能错过了一些 dunders(有意或无意),如果您想了解更多信息,这是一个很好的参考:https://www.python-course.eu/python3_magic_methods.php

    class Binary(int):
    
        def __new__(self, val):
            if type(val) is str:
                if len(val) > 1:
                    val = int(val, 2)
                else:
                    val = ord(val)
            return super().__new__(self, val)
    
        dunders_binary = "and rand add radd sub rsub mul rmul lshift rlshift " + \
                "rshift rrshift and rand or ror xor rxor"
    
        for dunder in ("__%s__" % s for s in dunders_binary.split()):
            locals()[dunder] = lambda self, other, __f=dunder: \
                    self.__class__(getattr(super(), __f)(other))
    
        dunders_unary = "neg pos invert"
    
        for dunder in ("__%s__" % s for s in dunders_unary.split()):
            locals()[dunder] = lambda self, __f=dunder: \
                    self.__class__(getattr(super(), __f)())
    
        def __repr__(self):
            return bin(self)
    
        def __str__(self):
            return bin(self)
    

    【讨论】:

    • 这其实是我最初的想法。谢谢!
    • 如果你让它成为公认的答案,更多的人可以看到 Python 的魔力。虽然目前的答案是在 Python 中使用二进制的标准方法。
    【解决方案3】:

    思考二进制/字节对​​于过去的程序员来说是多么有趣。今天使用 Python 的“切线”程序员可以走得很远,而不必过多担心计算机内部发生的事情。汇编代码?不!

    我是 Python 新手,发现它不支持无符号整数很有趣。

    了解或回忆十六进制字节由两个“半字节”组成可能对 OP 很有用。

    Python 文档包含“Bitwise Operations on Integer Types”部分。

    OP 和其他新的 Python 程序员可能会对以下程序感兴趣:

    #--------*---------*---------*---------*---------*---------*---------*---------*
    # Desc: bits and bytes and ascii
    #--------*---------*---------*---------*---------*---------*---------*---------*
    import sys
    
    while True:
    
        for i in range(0, 16):
            print(i, i.bit_length())
        print(255, (255).bit_length())
        print(256, (256).bit_length())
        print((16).to_bytes(1, byteorder='big',signed=False))
        print((255).to_bytes(1, byteorder='big',signed=False))
        b = (255).to_bytes(1, byteorder='big',signed=False)
        print(b)
        print(b[0])
        print("\nAscii Table")
        for i in range(0, 256):
            b = (i).to_bytes(1, byteorder='big',signed=False)
            print(b[0], b, ord(b), chr(ord(b)))
    
        sys.exit()
    

    【讨论】:

      猜你喜欢
      • 2023-02-21
      • 1970-01-01
      • 2011-04-22
      • 2010-11-03
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      相关资源
      最近更新 更多