私はファクトリデザインパターンを実装しようとしていますが、これまでこれを行ってきました。
import abc
class Button(object):
__metaclass__ = abc.ABCMeta
html = ""
def get_html(self, html):
return self.html
class ButtonFactory():
def create_button(self, type):
baseclass = Button()
targetclass = type.baseclass.capitalize()
return targetclass
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
print button_obj.create_button(b).get_html()
出力は、すべてのボタンタイプのHTMLである必要があります。
このようなエラーが発生します
AttributeError: 'str' object has no attribute 'baseclass'
ImageButton、InputButton、FlashButtonなどのさまざまなバリエーションを持つクラスを実装しようとしています。場所によっては、ボタン用に異なるhtmlを作成する必要がある場合があります
baseclass
が文字列値(_['image', 'input', 'flash']
_の1つ)を取得するため、存在しないstr
のb
属性を呼び出そうとしています。名前を表す文字列に従ってオブジェクトを作成する場合は、変数名とその値の間のマッピングを保持するglobals()
ディクショナリを使用できます。
_class Button(object):
html = ""
def get_html(self):
return self.html
class Image(Button):
html = "<img></img>"
class Input(Button):
html = "<input></input>"
class Flash(Button):
html = "<obj></obj>"
class ButtonFactory():
def create_button(self, typ):
targetclass = typ.capitalize()
return globals()[targetclass]()
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
print button_obj.create_button(b).get_html()
_
編集:globals()
またはlocals()
を使用することも良い習慣ではないため、可能であれば、次のように、関連するオブジェクトとその名前の間にマッピングを作成することをお勧めします。
_button_objects = {'image':Image,'flash':Flash,'input':Input}
_
_create_button
_を次のように置き換えます。
_def create_button(self, typ):
return button_objects[typ]()
_
ランタイム文字列に基づいてボタンインスタンスを作成する必要があると仮定すると、Buttonクラスとファクトリの代わりに、タイプの名前の辞書を用意するだけで済みます(chepnerが提案したように)。
buttonTypes = {"image" : Image,
"input": Input,
"flash" : Flash}
button = buttonTypes[name]()
print button.html
(これはここに直接入力されたので、詳細にいくつかの間違いがあるかもしれません)。 Pythonはダックタイプなので、基本タイプは必要ないかもしれません。
エラーの原因は次のとおりです。
_button = ['image', 'input', 'flash'] # button contains strings
for b in button: # b is a string
create_button(b) # argument 'type' is a string
type.baseclass... # hence the AttributeError
_
リストbutton
には、文字列としての名前ではなく、baseclass
属性を持つオブジェクトが含まれている必要があります。また、変数名としてtype
を使用しないでください。これは、Python標準ライブラリ関数type()
をシャドウするためです。