[Tutor] Fw: use of __new__
spir
denis.spir at free.fr
Fri Jun 12 15:29:54 CEST 2009
Le Fri, 12 Jun 2009 14:20:24 +0200,
"A.T.Hofkamp" <a.t.hofkamp at tue.nl> s'exprima ainsi:
> spir wrote:
> > Hello,
> >
> > I have (again) some issue using __new__.
> > What I need is basically to catch an object creation and yield an object
> > of an alternate type, when a condition is met.
> >
> > Basically, the outline looks like:
> >
> > class Normal(object):
> > def __new__(cls, arg):
> > if cond(arg):
> > # <yield instance of Special>
> > # expression is simply: Special(arg)
> > # must be __init__ialised !
> >
> > # Conceptually, nothing to change:
> > # <yield instance of Normal>
> > # must be __init__ialised !
> >
> > But I got issues in both cases:
> > * cannot find how to get Special objects initialised
> > * cannot find how to return Normal object
> > (also Normal's supertype has no explicite __new__, but it has an __init__)
>
> Maybe it's just me, but why don't you use a factory function?
>
> def make(args):
> if cond(args):
> return Special(args)
> else:
> return Normal(args)
;-)
Thank you, Albert -- but I (think I) can't.
It's generated code (from a parser generator) that uses a library. At write time, arguments are not known -- not even existent. I could check their "type" (know by the node), but some could be names, instead of expressions.
If this is too unclear, and you want to know more, read below in PS.
Denis
------
la vita e estrany
PS
The parser generator simply write python code that basically initiates pattern object from a of various types from a library.
The present issue happens for repetitions. The normal case works as follwows (I skip several arguments):
grammar:
foo : ('0'/"xyz")+
parser:
foo = Repetition([Choice(Char('0',...), Word("xyz",...)],...)
But in case the repeted pattern is a "Klass" (of characters, like in regexes), I want to yield instead a String, which is a specialised (char) repetition pattern type.
The meta-parser knows all needed information if you write eg:
digits : [0..9]+
You'll get a repetition node which holds (read: points to) a klass node. So I first let the generator sort out klass repetitions to write String expressions. Then I went back even higher to special-case strings in the meta-grammar itself.
But in the following case:
digit : [0..9]
digits : digit+
the repetition node holds a "name"! It's very common, indeed. And in such cases you'll never get a String. Stupid, no? The reason why I have to wait until python objects are generated before sorting String-s out.
I could let the code generator explore the parse tree to find a 'pattern' node which 'name' is 'digit' but it's overly complicated, compared to letting the generated code do this job -- I guess.
------
la vita e estrany
More information about the Tutor
mailing list