我在某些场合遇到了python中的标志概念,例如在wxPython中。一个例子是框架对象的初始化。 传递给"样式"的属性。
frame = wx.Frame(None, style=wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
我真的不明白标志的概念。我什至没有找到一个可靠的解释,术语"标志"在Python中到底是什么意思。如何将所有这些属性传递给一个变量? 我唯一能想到的是"|"字符用作布尔运算符,但在这种情况下,传递给 style 的所有属性不是都计算为单个布尔表达式吗?
在这个意义上,标志通常意味着单个整数值中的位。|
是 ususal bit-or 运算符。
假设wx.MAXIMIZE_BOX=8
和wx.RESIZE_BORDER=4
,如果您或他们在一起,您将获得 12。在这种情况下,您实际上可以使用+
运算符而不是|
。
尝试打印常量print(wx.MAXIMIZE_BOX)
等,您可能会得到更好的理解。
标志并不是 Python 独有的;这是许多语言中使用的概念。它们建立在位和字节的概念之上,其中计算机内存基本上使用大量标志来存储信息。这些标志是位,它们要么关闭(值0
(,要么打开(值1
(,即使您通常以至少 8 个此类标志(字节,对于较大的组,8 的倍数,特定于计算机体系结构(的组访问计算机内存。
整数是存储在字节中的信息的简单而常见的表示形式;单个字节可以存储 0 到 255 之间的任何整数,并且使用更多的字节可以表示更大的整数。但是这些整数仍然由打开或关闭的位组成,因此您可以将这些整数用作启用或禁用功能的开关。传入启用或禁用特定位的特定整数值,以打开和关闭要素。
因此,一个字节由 8 个标志(bits(组成,启用其中一个意味着你有 8 个不同的整数; 1、2、4、8、16、32、64 和 128,您可以将这些数字的组合传递给像 wxPython 这样的库来设置不同的选项。对于多字节整数,数字只是增加一倍。
但是你a(不想记住每个数字的含义,b(需要一种方法将它们组合成一个整数来传递。
|
运算符执行后者,wx.MAXIMIZE_BOX
、wx.RESIZE_BORDER
等名称只是整数值的符号常量,由 wxWidget 项目在各种 C 头文件中设置,并用wx/toplevel.h
和wx/defs.h
总结:
/*
Summary of the bits used (some of them are defined in wx/frame.h and
wx/dialog.h and not here):
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | _ wxCENTRE
| | | | | | | | | | | | | | ____ wxFRAME_NO_TASKBAR
| | | | | | | | | | | | | _______ wxFRAME_TOOL_WINDOW
| | | | | | | | | | | | __________ wxFRAME_FLOAT_ON_PARENT
| | | | | | | | | | | _____________ wxFRAME_SHAPED
| | | | | | | | | | ________________ wxDIALOG_NO_PARENT
| | | | | | | | | ___________________ wxRESIZE_BORDER
| | | | | | | | ______________________ wxTINY_CAPTION_VERT
| | | | | | | _________________________
| | | | | | ____________________________ wxMAXIMIZE_BOX
| | | | | _______________________________ wxMINIMIZE_BOX
| | | | __________________________________ wxSYSTEM_MENU
| | | _____________________________________ wxCLOSE_BOX
| | ________________________________________ wxMAXIMIZE
| ___________________________________________ wxMINIMIZE
______________________________________________ wxSTAY_ON_TOP
...
*/
和
/*
Summary of the bits used by various styles.
High word, containing styles which can be used with many windows:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | _ wxFULL_REPAINT_ON_RESIZE
| | | | | | | | | | | | | | ____ wxPOPUP_WINDOW
| | | | | | | | | | | | | _______ wxWANTS_CHARS
| | | | | | | | | | | | __________ wxTAB_TRAVERSAL
| | | | | | | | | | | _____________ wxTRANSPARENT_WINDOW
| | | | | | | | | | ________________ wxBORDER_NONE
| | | | | | | | | ___________________ wxCLIP_CHILDREN
| | | | | | | | ______________________ wxALWAYS_SHOW_SB
| | | | | | | _________________________ wxBORDER_STATIC
| | | | | | ____________________________ wxBORDER_SIMPLE
| | | | | _______________________________ wxBORDER_RAISED
| | | | __________________________________ wxBORDER_SUNKEN
| | | _____________________________________ wxBORDER_{DOUBLE,THEME}
| | ________________________________________ wxCAPTION/wxCLIP_SIBLINGS
| ___________________________________________ wxHSCROLL
______________________________________________ wxVSCROLL
...
*/
|
运算符是按位 OR 运算符;它组合了两个整数的位,每个匹配位都配对并根据 OR 的布尔规则转换为输出位。当您对这些整数常量执行此操作时,您将获得一个启用了多个标志的新整数。
所以表达
wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX
给你一个整数,其中设置了位数 9、6、11、29 和 12;在这里,我使用'0'
和'1'
字符串来表示位,int(..., 2)
将这些字符串的序列解释为二进制表示法中的单个整数:
>>> fourbytes = ['0'] * 32
>>> fourbytes[9] = '1'
>>> fourbytes[6] = '1'
>>> fourbytes[11] = '1'
>>> fourbytes[29] = '1'
>>> fourbytes[12] = '1'
>>> ''.join(fourbytes)
'00000010010110000000000000000100'
>>> int(''.join(fourbytes), 2)
39321604
在接收端,可以使用&
按位 AND 运算符来测试是否设置了特定标志;如果未设置该标志,则返回0
,如果已设置标志位,则返回与分配给标志常量的相同整数。在 C 和 Python 中,非零数在布尔测试中都是正确的,因此通常使用以下方法测试特定标志:
if ( style & wxMAXIMIZE_BOX ) {
用于确定设置了特定标志,或
if ( !(style & wxBORDER_NONE) )
以测试相反的情况。
它是一个布尔运算符 - 不是逻辑运算符,而是按位运算符。wx.MAXIMIZE_BOX
和其余的通常是整数,是 2 的幂 - 1、2、4、8、16...这使得其中只有一个位是 1,其余的都是 0。当你将按位OR(x | y
(应用于这样的整数时,最终的效果是它们组合在一起:2 | 8
(0b00000010 | 0b00001000
(变成10(0b00001010
(。稍后可以使用按位 AND (x & y
( 运算符将它们撬开,也可以调用掩码运算符:10 & 8 > 0
将为 true,因为与8
对应的位已打开。