开发者

How to optionally import/construct class to member variable that will support IDE autocomplete

I have a Python library design that I'm trying to clean up, but I noticed that one piece isn't auto-completing in Eclipse/PyDev. I'm familiar enough for this not to be a problem for me, but its a library that others will end up using and auto-complete that doesn't work for a feature chunk won't do.

I'll just explain quickly what its trying to do, I re-created the design below. It all works, but auto-complete isn't useful. Maybe someone can just set me straight.

In module test_module2.py

import Main from test_module.py

from test_module import Main

class Second(object):
    _main = Main
    def set_main_variable(self, var):
        self._main.variable = var

In module test_module.py

import sys

class Main(object):
    variable = 0
    second = None
    def __init__(self):
        for x in sys.modules.keys():
            if x.endswith("test_module2"):
                y = sys.modules[x]
            self.second = y.Second()
                self.second._main = self

    def print_variable(self):
        print self.variable

In application test.py

import test_module
import test_module2

if __name__ == "__main__":
    m = test_module.Main()
    m.second.set_main_variable(10)
    m.print_variable() # prints 10

With this, if the test_module2.py module is imported, you can access it via a separate namespace member variable Main.second. Keeps things separate, and if the module isn't available, then you don't have access to Second's features.

In test_module2.py, Main is imported (you can't use Second without Main anyways) and _main is default to Main. This allows auto-complete in Second when you're working on the parent _main reference that's setup when Main is constructed and Second was imported. (this is good)

In Main, Second is optional and is never directly calls from Main methods. So auto-complete isn't necessary. (this is fine)

In __main__, auto-complete naturally works for Main member variables and methods, but doesn't work with m.second. I can't default m.second to anything because I'd end up having to import test_module2.py from test_module.py. It's optional and is defined by __main__'s import of test_module2.py. e.g. if __main__ imports test_module2.py, then Second is automatically available to the application.

Anyone have a better way to have an optionally imported module/class construct to a member variable, that will work with IDE auto-completion?

Thanks in advance for any ideas.

I'm going to come to the conclusion that auto-completion with PyDev will only see a variable set to a class's members if the parent class inherits from it, or defaults the variable to the class itself. For example:

class Main(object):
    second = Second

Then in __main__ you can auto-complete: main.second...

That or Main has to inherit from Second.

Ok, I need to go back and complain that this library design isn't going to work with IDE auto-completion. See if I can use an wrapper class to inherit if the import test_module2 is present and clean things up.

My solution: Here's what I came up with:

In module test_module2.py

import test_module
class Second(object):
    _variable = 0 # overrided by Main's _variable
    def set_main_variable(self, var):
        self._variable = var

class Main(test_module.Main, Second):
    def __init__(self):
        super(Main, self).__init__()

In module test_module.py

class Main(o开发者_高级运维bject):
    _variable = 0
    second = None
    def __init__(self):
        super(Main, self).__init__()

    def print_variable(self):
        print self._variable

Now! In test.py if you import test_module or test_module2 (not both), you can construct Main with or without Second's added functionality. Second will have access to everything in Main, and because Main is inheriting Second, auto-complete works.

In application test.py

#import test_module
import test_module2

if __name__ == "__main__":
    m = test_module.Main()
    m.set_main_variable(10)
    m.print_variable() # prints 10

I don't know if I can easily move Second's methods into a sub-namespace, like Main.second.set_variable(). I would have to explicitly set a Main reference within Second after Main constructs it as a variable, (in Main init, self.second = Second()) and not have Second inherited by Main. Then you could call m.second.set_main_variable(10), and keep all Second methods accesible from Main under the .second namespace.


First, Simple is better than complex -- your design appears to be complicated for no good reason. Maybe you should provide some details about your actual library.

Second, with Python as a dynamically typed language, it's just natural that there are cases when your IDE fails to auto-complete because your IDE has a static perspective. And you definitely shouldn't programm to suite the capabilites of your IDE.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜