ページへ戻る
印刷
Python/FlagとIntFlag
をテンプレートにして作成 ::
NJF Wiki
xpwiki
:Python/FlagとIntFlag をテンプレートにして作成
開始行:
*Flag
''注意'':FlagやIntFlagは列挙型Enumの一種です。Enumを知ら...
昔からあるプログラムの書き方で、ビット毎にフラグを設定し...
ビット単位で管理するのでメモリが節約できます。また一般に...
これと同じようなことを実現するPythonのクラスがFlagです。
例えば、ゲームで状態異常を定義したいとして、次のようなク...
from enum import Flag
class PlayerStatus(Flag):
SLEEP = 1 #睡眠
POISON = 2 #毒
PARALYSIS = 4 #麻痺
ここで1,2,4は二進数で書けば1,10,100の事で、それぞれ1ビッ...
このように手で書くこともできますが、Python3.6で追加された...
from enum import Flag ,auto
class PlayerStatus(Flag):
SLEEP = auto()
POISON = auto()
PARALYSIS = auto()
for s in PlayerStatus:
print(s.name,s.value)
結果:
SLEEP 1
POISON 2
PARALYSIS 4
これの良いところは一つの変数に複数のフラグを設定できるこ...
例えば、睡眠かつ毒状態のステータスは
status = PlayerStatus.SLEEP | PlayerStatus.POISON
と書きます。これを表示させると、
print(status)
結果:
PlayerStatus.POISON|SLEEP
というふうに、実際にフラグが複数設定されています。
また、Flag型はフラグの状態をわかりやすく出力してくれるの...
フラグが立っているかどうかは「&」でチェックします。
status = PlayerStatus.SLEEP | PlayerStatus.POISON
if status & PlayerStatus.SLEEP:
print("SLEEP!")
if status & PlayerStatus.POISON:
print("POISON!")
if status & PlayerStatus.PARALYSIS:
print("PARALYSIS!")
結果:
SLEEP!
POISON!
フラグをオフにするには以下のように「&」と「~」(否定)を...
status = PlayerStatus.SLEEP | PlayerStatus.POISON
status = PlayerStatus.SLEEP & (~PlayerStatus.POISON)
if status & PlayerStatus.SLEEP:
print("SLEEP!")
if status & PlayerStatus.POISON:
print("POISON!")
if status & PlayerStatus.PARALYSIS:
print("PARALYSIS!")
結果:
POISON!
また、Flag型はFlag型同士でなければ演算できないことに注意...
Intと演算したいときには次のIntFlag型を使います。
*IntFlag
IntFlag型はFlag型とほぼ同じ機能がありますが、Flag型とは異...
つまり、Flag型では次の処理はエラーとなります。
status = PlayerStatus.SLEEP | 2
print(status)
Flag型での結果:
Traceback (most recent call last):
File "enumflgs.py", line 50, in <module>
status = PlayerStatus.SLEEP | 2
TypeError: unsupported operand type(s) for |: 'PlayerSta...
しかし、IntFlag型なら問題なく実行されます。
IntFlag型での結果:
PlayerStatus.POISON|SLEEP
直接数値が使えないのでFlag型の方がマジックナンバーが発生...
一方でIntFlag型は計算結果や外部入力の数値をそのままフラグ...
基本的にFlag型を使い、フラグを整数と演算する必要がある場...
*まとめ
Flagはビット演算でのフラグの管理を使いやすくするクラスで...
IntFlagはそのFlagを整数としても扱えるようにした物です。
フラグがたくさんあって整理が難しい場合や、少しでも処理を...
ただし、現在のようにメモリも大容量でCPUも速くなった時代に...
フラグが少なく処理が簡単な場合は真偽型boolをそのまま使う...
終了行:
*Flag
''注意'':FlagやIntFlagは列挙型Enumの一種です。Enumを知ら...
昔からあるプログラムの書き方で、ビット毎にフラグを設定し...
ビット単位で管理するのでメモリが節約できます。また一般に...
これと同じようなことを実現するPythonのクラスがFlagです。
例えば、ゲームで状態異常を定義したいとして、次のようなク...
from enum import Flag
class PlayerStatus(Flag):
SLEEP = 1 #睡眠
POISON = 2 #毒
PARALYSIS = 4 #麻痺
ここで1,2,4は二進数で書けば1,10,100の事で、それぞれ1ビッ...
このように手で書くこともできますが、Python3.6で追加された...
from enum import Flag ,auto
class PlayerStatus(Flag):
SLEEP = auto()
POISON = auto()
PARALYSIS = auto()
for s in PlayerStatus:
print(s.name,s.value)
結果:
SLEEP 1
POISON 2
PARALYSIS 4
これの良いところは一つの変数に複数のフラグを設定できるこ...
例えば、睡眠かつ毒状態のステータスは
status = PlayerStatus.SLEEP | PlayerStatus.POISON
と書きます。これを表示させると、
print(status)
結果:
PlayerStatus.POISON|SLEEP
というふうに、実際にフラグが複数設定されています。
また、Flag型はフラグの状態をわかりやすく出力してくれるの...
フラグが立っているかどうかは「&」でチェックします。
status = PlayerStatus.SLEEP | PlayerStatus.POISON
if status & PlayerStatus.SLEEP:
print("SLEEP!")
if status & PlayerStatus.POISON:
print("POISON!")
if status & PlayerStatus.PARALYSIS:
print("PARALYSIS!")
結果:
SLEEP!
POISON!
フラグをオフにするには以下のように「&」と「~」(否定)を...
status = PlayerStatus.SLEEP | PlayerStatus.POISON
status = PlayerStatus.SLEEP & (~PlayerStatus.POISON)
if status & PlayerStatus.SLEEP:
print("SLEEP!")
if status & PlayerStatus.POISON:
print("POISON!")
if status & PlayerStatus.PARALYSIS:
print("PARALYSIS!")
結果:
POISON!
また、Flag型はFlag型同士でなければ演算できないことに注意...
Intと演算したいときには次のIntFlag型を使います。
*IntFlag
IntFlag型はFlag型とほぼ同じ機能がありますが、Flag型とは異...
つまり、Flag型では次の処理はエラーとなります。
status = PlayerStatus.SLEEP | 2
print(status)
Flag型での結果:
Traceback (most recent call last):
File "enumflgs.py", line 50, in <module>
status = PlayerStatus.SLEEP | 2
TypeError: unsupported operand type(s) for |: 'PlayerSta...
しかし、IntFlag型なら問題なく実行されます。
IntFlag型での結果:
PlayerStatus.POISON|SLEEP
直接数値が使えないのでFlag型の方がマジックナンバーが発生...
一方でIntFlag型は計算結果や外部入力の数値をそのままフラグ...
基本的にFlag型を使い、フラグを整数と演算する必要がある場...
*まとめ
Flagはビット演算でのフラグの管理を使いやすくするクラスで...
IntFlagはそのFlagを整数としても扱えるようにした物です。
フラグがたくさんあって整理が難しい場合や、少しでも処理を...
ただし、現在のようにメモリも大容量でCPUも速くなった時代に...
フラグが少なく処理が簡単な場合は真偽型boolをそのまま使う...
ページ名: