use of __new__ to permit "dynamic" completion within (any?) IDE ?
gst
g.starck at gmail.com
Wed Dec 8 07:01:38 EST 2010
On 8 déc, 11:45, Steven D'Aprano <steve
+comp.lang.pyt... at pearwood.info> wrote:
> On Tue, 07 Dec 2010 07:52:06 -0800, gst wrote:
> > Hi,
>
> > But in my IDE I want the completion to also work from within the lower
> > level module when it's refering to the object passed from the upper
> > level:
>
> "The completion"? What do you mean?
Hi,
I mean the autocompletion feature of my IDE :
when I type "object." then on the "." it shows me possible members/
methods of the 'object'. depending on what my IDE can guess about the
object possible type(s) ; in the worst case it can't guess nothing
about it and that's my point below..
> > Well, I'm sure I'm not very clear in my terms (and probably a bit long
> > in the sentence) so here it is in code:
>
> I'm afraid I have to agree with your, your description is not clear to me.
I hope I'm now ;)
> Unfortunately, neither is your code, because I don't understand *why* you
> do the things you do.
damn. ok let's go..
> > file module1.py:
>
> > from subpackage.module2 import class2
>
> Is it relevant that class2 comes from another module?
yes. hmmm or maybe not completely.. I think it only highly depends on
what the IDE can guess on an object type used inside some methods
depending on the files hierarchy..
> Would your concept work if class1 and class2 were defined in the same file?
I guess yes also.
> > class class1(object):
>
> > def __new__(cls, _self=None, *args, **kwargs):
> > if _self: ## we've been passed an instance already
> > initialyzed
> > ## so directly return it instead of creating a
> > new object.
> > return _self
> > return object.__new__(cls)
>
> Depending on your application, this may be an unsafe assumption. If the
> caller says class1("spam"), your class will return "spam". This may or
> may not be what you want.
I'm always passing the good object type when I do this.
> > def __init__(self, _self=None, *args, **kwargs):
> > if _self: ## we've been passed an instance already
> > initialyzed
> > ## so directly returns
> > ## assert(self is _self) ?
> > return
> > self.object2 = class2(object1=self, "blip", "blop") # others
> > init
>
> Okay, this seems like a fairly straightforward case of adding an
> attribute to your instance that includes a reference to itself. No big
> deal... there's nothing wrong with this, although you are creating a
> reference cycle, which is somewhat of a (mild) code-smell.
that is a worry effectively. (hmm when you say it's a case of adding
an attribute that includes a ref to itself it's not really that (or i
badly understand) : it's adding an attribute to a lower level class
instance that contains a ref to an upper level class instance (which
also contains a ref to the lower level class' instance and that's the
cycle (and that's a bit my worry))
> > file module2.py:
>
> > class class2(object):
>
> > def __init__(self, object1, *args, **kwargs):
>
> > from ..module1 import class1
>
> Now you have a circular import, and that's a pretty major code smell.
> That's dangerous. Try to avoid it. Perhaps the easiest way to avoid it is
> to place class1 and class2 in the same module, and stop writing Java :)
damn if this looks like Java it's really not my will ; I've not made
Java anymore for probably 10 years !
I'll try by putting class1 and class2 in same module (or at same
directory level first) and see if that can do it..
>
> > self.object1 = class1(_self=object1) ## instead of:
> > self.object1 = object1
>
> > ## others functions and/or init..
> > ## where now I've completion working on self.object1 : ## if I
> > add(or remove) fields/methods in module1 (and save) then ## I have
> > them available(or disappeared) in the completion when
> > executed from this submodule.
> > ## This ofcourse permits to save me of remembering all of the
> > class1 attributes/methods when I'm working with self.object1 from within
> > one of class2 methods.
>
> I'm afraid I don't understand what you mean here in these comments. What
> do you mean, "save me of (from?) remembering all the class1 attributes/
> methods..." -- how does it save you from knowing the methods? Whether you
> write this:
>
> instance = class1()
> instance.method()
>
> or this:
>
> instance = class1()
> another_instance = class2(instance)
> another_instance.object1.method()
>
> you still need to know the name "method".
>
> It seems to me that this scheme is unnecessarily complex, convoluted and
> confusing, for very little gain. Perhaps you could try explaining what
> you hope to accomplish, giving examples?
Effectively I recognise that this seems like a bit silly/odd .. but as
it's working I wanted some advises so ;)
As I told I try to have some kind of "ultimate" autocompletion, always
working for this kind of case (I know exactly that a certain member of
a certain class' instance will always have the same type but my IDE
doesn't seem to guess/know it.. ; I guess the best answer would be :
bad IDE, change IDE but I'm guessing that others IDE can't do a lot
better in this case.
Anyway many thanks for your reply ; I'll do some further tests with
your comments already..
regards,
greg.
nb: so this "hack" is only relevant during dev ; once the project
would be finished the "hack" could be removed (i.e : in class2 init I
would directly do : self.object1 = object1)
More information about the Python-list
mailing list