use of __new__ to permit "dynamic" completion within (any?) IDE ?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Wed Dec 8 05:45:55 EST 2010
On Tue, 07 Dec 2010 07:52:06 -0800, gst wrote:
> Hi,
>
> I met a situation where I was passing an object created in/with an upper
> level module class to a lower level module class' instance in one of its
> __init__ argument and saving a ref of the upper object in that lower
> level class' new instance.
>
> 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?
> 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.
Unfortunately, neither is your code, because I don't understand *why* you
do the things you do.
> files:
> module1.py
> subpackage/module2.py
>
>
> file module1.py:
>
> from subpackage.module2 import class2
Is it relevant that class2 comes from another module? Would your concept
work if class1 and class2 were defined in the same file?
By the way, it's conventional (but not compulsory) to name classes with
an initial capital letter, and instances in all lowercase.
> 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.
> 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.
> 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 :)
> 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?
--
Steven
More information about the Python-list
mailing list