0

I have just started with Python and have been studying the code of a particular library. The library contains an Html class whose initialization looks like this

page = Html()(  # add tags inside the one you created calling the parent
    Head()(  # add multiple tags in one call
        Meta(charset='utf-8'),  # add tag attributes using kwargs in tag initialization
        Link(href="my.css", typ="text/css", rel="stylesheet")
    ),
    body=Body()(  # give them a name so you can navigate the DOM with those names
        Div(klass='linkBox')(
            A(href='www.foo.com')
        ),
        (P()(text) for text in my_text_list),  # tag insertion accepts generators
        another_list  # add text from a list, str.join is used in rendering
    )
)

and the class definition looks like this

class Html(Tag):
    """Html tag have a custom render method for it needs to output the Doctype tag outside the main page tree.
    Every Html object is associated with a Doctype object (default doctype code: 'html').
    """
    __tag = 'html'

    def __init__(self, *args, **kwargs):
        # Setting a default doctype: 'html'
        doctype = kwargs.pop('doctype', 'html')
        super().__init__(**kwargs)
        self.doctype = Doctype(doctype)

My question is why is the second set of parentheses needed in the Html object initialization? The init does not return a function here.

The full code can be found here

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
Pharaoh
  • 712
  • 1
  • 9
  • 33

1 Answers1

3

It looks like Tag or some other base class has defined __call__ such that tags are callable objects. That lets each tag be constructed with the attributes passed to the constructors in the first set of parentheses (handled by __init__) and the tag contents passed in the second set (handled by __call__).

John Kugelman
  • 349,597
  • 67
  • 533
  • 578