对象构造函数中的 Python 标志



我在某些场合遇到了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=8wx.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_BOXwx.RESIZE_BORDER等名称只是整数值的符号常量,由 wxWidget 项目在各种 C 头文件中设置,并用wx/toplevel.hwx/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对应的位已打开。

最新更新