472,127 Members | 2,054 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,127 software developers and data experts.

Good idea to use a class as function with __new__?

Hi,

I am implementing som code generation and want to to use some variant
of the template method pattern.

What I came up with is to have a class with the common part
in a method and the subclasses can then override the Customize methods
to do their own special part.

Now to the question I use the __new__ to return the result instead
of the instance. So that the class is used as an function.

So insted of having.

a = Template()
result = a.__TemplateMethod(preifix="foo")

I can write:

result = Template(prefix="foo")

class Template(object):

def __init__(cls, *args, **kwds):
pass

def __new__(cls, *args, **kwds):
obj = super(Template, cls).__new__(cls, *args, **kwds)
return obj.__TemplateMethod(*args, **kwds)

def Customize1(self, prefix="hello", *args, **kwds):
return prefix+"1\n"

def Customize2(self, prefix="hello", *args, **kwds):
return prefix+"2\n"

def __TemplateMethod(self, *args, **kwds):
result = ""
result += self.Customize1(*args, **kwds)
result += self.Customize1(*args, **kwds)
return result
b = Template("foo")

print b

May 28 '07 #1
2 950
En Mon, 28 May 2007 09:17:30 -0300, glomde <tb****@yahoo.comescribió:
I am implementing som code generation and want to to use some variant
of the template method pattern.

What I came up with is to have a class with the common part
in a method and the subclasses can then override the Customize methods
to do their own special part.

Now to the question I use the __new__ to return the result instead
of the instance. So that the class is used as an function.
It works, and I don't see any big problems, but I don't *like* that.
I'd use __call__ instead; that is, write __new__ and __init__ normally -if
you need them at all- and move the magic to __call__:

def __call__(self, *args, **kwds):
return self.__TemplateMethod(*args, **kwds)

x = Template()(prefix="foo")
or perhaps:
x = Template(prefix="foo")()

I think the extra () improves readability - it's clear that x comes from a
function call, it's not a Template instance as one would expect from your
original code.
And depending on the application, you could keep the instances and call
them with different arguments - with the original code you always create a
new instance just to discard it immediately.

--
Gabriel Genellina

May 28 '07 #2

Gabriel Genellina wrote:
def __call__(self, *args, **kwds):
return self.__TemplateMethod(*args, **kwds)

x = Template()(prefix="foo")
or perhaps:
x = Template(prefix="foo")()

I think the extra () improves readability - it's clear that x comes from a
function call, it's not a Template instance as one would expect from your
original code.
And depending on the application, you could keep the instances and call
them with different arguments - with the original code you always create a
new instance just to discard it immediately.

--
Thanks for the reply. I was considering __call__ but in my case it is
really something
that will be discarded immediately. And right now it is is implemented
as function
where I have arguments to send in which customize functions something
like:

def Template(self, func1=Customize1, func2= Customize2, *args,
**kwds):
func1(*args, **kwds)
func2(*args, **kwds)

So I just wanted to organize it a little bit nicer and be able to
subclass instead of
sending in function pointers. But that had the same interface.

But you are right the extra () does make it clearer, so I probably go
for that.

Cheers,

/T
Gabriel Genellina
May 28 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Todd Johnson | last post: by
2 posts views Thread by Fernando Rodriguez | last post: by
9 posts views Thread by Joel Hedlund | last post: by
9 posts views Thread by Gregor Horvath | last post: by
2 posts views Thread by Steven D'Aprano | last post: by
7 posts views Thread by Jeffrey Barish | last post: by
44 posts views Thread by Steven D'Aprano | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.