動的に変数名を生成することは、ほとんどの場合、悪いアプローチです。辞書を使う!
bonedict = {'boneList_head': ['def_neck', 'def_armbase']}
itemType='head'
def selectBones(itemType):
bones = bonedict['boneList_' + itemType]
for bone in bones:
cmds.select(bone, tgl=True)
私の以前の回答 (私の編集履歴に表示されます) は無視してください。しかし、私はその愚かさを動的変数名生成のせいにしています!
動的な変数名の生成がなぜ悪い考えなのかを詳しく説明しましょう。
動的変数生成では、変数名の定義がマスクされるためです。何が定義されていて、何が定義されていないかを見分けるのは難しいため、誤って変数を再定義するのは簡単です。これは、潜在的なバグの主な原因です。
動的な変数操作は、別の難読化層の下に状態の変化を隠すためです。これは、ディクショナリまたはリストを作成するときはいつでも、ある程度当てはまります。しかし、リストや辞書には少し余分な思考が必要になると予想されます。一方、変数名は非常に単純でなければなりません。変数の定義と再定義を理解するために深く考える必要がある場合、何かが間違っています。
動的変数生成は名前空間を汚染するためです。自動的に生成しなければならないほど多くの変数がある場合、それらは関数のローカルではなく、グローバル名前空間ではなく、独自の名前空間に存在する必要があります。Linux カーネルのスタイル ガイドで、Linus Torvalds は、関数に 5 ~ 10 個を超えるローカル変数がある場合、何か間違ったことをしているとアドバイスしています。
動的変数の生成は結合度が高くなり、これは悪いことです。ディクショナリに値を代入すると、牛が家に帰るまでそのディクショナリを前後に渡すことができ、誰もが知る必要があるのはそのディクショナリだけです。モジュールのグローバル名前空間で変数名を動的に作成する場合、別のモジュールがそれらの変数名にアクセスしたい場合、それらが生成された方法、そのモジュール内の他のどの変数が定義されているかなどについてすべてを知る必要があります。また、変数の受け渡しははるかに複雑になります。モジュール自体への参照を渡す必要があります。おそらく、sys.modules
またはその他の疑わしい構造を使用します。
動的変数生成が醜いからです。eval
きれいに見えますが、実際はそうではありません。何でもできます。何でもできる関数は、一見しただけでは何をしているのかわからないため、良くありません。明確に定義された関数は、1 つのことを適切に実行します。そうすれば、その関数を見るときはいつでも、何が起こっているかを正確に知ることができます。が表示されている場合eval
、文字通り何でも起こっている可能性があります。この意味で、eval
のようなものgoto
です。の問題goto
は、正しく使用できないことではありません。それは、あらゆる可能な正しい使用のためにgoto
、恐ろしいほど間違った使い方が 5 億通りあります。セキュリティの問題についてはここでは触れませんeval
。