web-dev-qa-db-ja.com

ファクトリデザインパターン

私はファクトリデザインパターンを実装しようとしていますが、これまでこれを行ってきました。

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を作成する必要がある場合があります

13
ajknzhol

baseclassが文字列値(_['image', 'input', 'flash']_の1つ)を取得するため、存在しないstrb属性を呼び出そうとしています。名前を表す文字列に従ってオブジェクトを作成する場合は、変数名とその値の間のマッピングを保持する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]()
_
13
Elisha

ランタイム文字列に基づいてボタンインスタンスを作成する必要があると仮定すると、Buttonクラスとファクトリの代わりに、タイプの名前の辞書を用意するだけで済みます(chepnerが提案したように)。

buttonTypes = {"image" : Image,
               "input": Input,
               "flash" : Flash}

button = buttonTypes[name]()
print button.html

(これはここに直接入力されたので、詳細にいくつかの間違いがあるかもしれません)。 Pythonはダックタイプなので、基本タイプは必要ないかもしれません。

3
Pete

エラーの原因は次のとおりです。

_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()をシャドウするためです。

3
jonrsharpe