0

これは、Flask内でテンプレートを作成しているJinja2に固有のものです(ただし、どちらにも特に関連しているわけではなく、より一般的なものを構築するために作業しているコンテキストにすぎません)。

class MultipleMacroFor(object):
    def __init__(self, macro):
        self.macro = macro

    def renderable(self, macro_var):
        return get_template_attribute(self.macro, macro_var)

class ResponseItemMacros(MultipleMacroFor):
    def __init__(self):
        super(ResponseItemMacros, self).__init__(macro="macros/response_items.html")

    @property
    def general_macro(self):
        return self.renderable('general_macro')

RI = ResponseItemMacros()

ユースケースの例:

 RI.general_macro # returns the renderable 'general_macro' from 'macros/response_items.html' that can be used with in a Jinja2 template

私はこれに変えたい:

class MultipleMacroFor(object):
    def __init__(self, macro, which_macros):
          self.macro = macro
          self.which_macros = which_macros

     # take which_macros and have them each be returnable as in the function above but
     # respond to the more general case, not specifically requiring construction  
     # @property
     # def (passed in var which_macro)(self):
     #   return self.renderable(passed in var which_macro)

RI = MultipleMacroFor(macro="macros/response_items.html", macros=['general', 'etc', 'etal'])

次にユースケース:

RI.general_macro #as above but without having to construct the intermediate ResponseItemsMacros class

渡されたリストはプロパティとして呼び出され、渡されたリストに基づいて動的に構築され、最初の例として手動で作成されません。最初の例では、使用するインスタンスを2つのクラスから手動で構築する必要があります。2つ目は、呼び出されるプロパティを使用してインスタンス化できる1つのクラスのみを使用することです。これは、レンダリング可能な関数を介して機能し、関連する名前付きマクロを生成します。

私だけがこのATMのやり方を正確に知りません。任意の入力をいただければ幸いです。

4

1 に答える 1

0

インスタンスごとのプロパティを持つことはできません(または、少なくともget_attributeをいじることなくしてはいけません。これは、本当に避けるべきものです)。最も簡単な解決策は、getattrを使用することです。

class MultipleMacroFor(object):
    def __init__(self, macro, names):
        self._macro = macro
        self._names = names

    def get_renderable(self, macro_var):
        return get_template_attribute(self.macro, macro_var)

    def __getattr__(self, name):
        if name in self._names:
            return self.get_renderable(name)
        raise AttributeError(
            "object %s has no attribute '%s'" % (
                type(self).__name__, name)
            )

より複雑な方法は、サブクラスを動的に構築してからインスタンス化することです。

class MultipleMacroFor(object):
    def __init__(self, macro, names):
        self._macro = macro
        self._names = names


    def get_renderable(self, macro_var):
        return get_template_attribute(self.macro, macro_var)

def MultipleMacroForFactory(macro, names):
    attrs = dict()
    for name in names:
        attrs[name] = property(
            lambda self, name=name: self.get_renderable(name)
            )

    clsname = "MultipleMacroFor%s" % "".join(
        name.capitalize() for name in names
        )

    return type(clsname, (MultipleMacroFor,), attrs)(macro, names)
于 2013-03-25T16:08:57.963 に答える