用Python可变长度整数取消设置标志中的单个位安全吗?

用Python可变长度整数取消设置标志中的单个位安全吗?,python,bit-manipulation,Python,Bit Manipulation,在我的程序(用Python 3.4编写)中,我有一个包含各种标志的变量,例如: FLAG_ONE = 0b1 FLAG_TWO = 0b10 FLAG_THREE = 0b100 status = FLAG_ONE | FLAG_TWO | FLAG_THREE 100000010000 # status & ~10000 # ~FLAG 设置另一个标志很容易 status |= FLAG_FOUR 但是如果我明确地想要清除一个标志呢?我愿意 status &

在我的程序(用Python 3.4编写)中,我有一个包含各种标志的变量,例如:

FLAG_ONE = 0b1
FLAG_TWO = 0b10
FLAG_THREE = 0b100
status = FLAG_ONE | FLAG_TWO | FLAG_THREE
  100000010000 # status
&       ~10000 # ~FLAG
设置另一个标志很容易

status |= FLAG_FOUR
但是如果我明确地想要清除一个标志呢?我愿意

status &= ~FLAG_THREE
这种方法安全吗?由于Python中没有定义整数的大小,如果
status
FLAG\u THREE
的大小不同怎么办


status
需要是一个位字段,因为我需要这个值用于硬件协议。)

清除标志可以使用

status &= ~FLAG_THREE
因为Python将这些被否定的值视为负值:

>>> ~1L
-2L
>>> ~1
-2
>>> ~2
-3
因此,
&
运算符可以适当地操作并产生所需的结果,而不考虑操作数的长度,因此
0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111


在另一个方向(右侧比左侧长),它仍然有效,因为有多余的
1
位并不重要。

使用这种方法应该是安全的,是的

Python中的
~
被简单地实现为
-(x+1)
(参见),负数被视为在开始处填充了任意数量的1。从:

当然,Python不使用8位数字。它过去使用的比特数是你机器的本地比特数,但由于这是不可移植的,所以最近它改用无限比特数。因此,按位运算符将数字-5视为写入“…111111111011”

换句话说,使用按位and和
&
可以保证这些1将
~FLAG
的长度(一个负整数)填充到
状态的长度上。例如:

FLAG_ONE = 0b1
FLAG_TWO = 0b10
FLAG_THREE = 0b100
status = FLAG_ONE | FLAG_TWO | FLAG_THREE
  100000010000 # status
&       ~10000 # ~FLAG
被视为

  100000010000
& 111111101111

= 100000000000 # new status 

此行为在源代码中的注释中进行了描述。

您是否尝试过在官方Python文档中找到此行为的定义?我查看了文档页面,但找不到与wiki页面中描述的行为相关的要点。当然,我很可能忽略了什么。