如何选择性地导入/构造类到支持 IDE 自动完成的成员变量

发布于 2024-12-02 23:04:41 字数 3247 浏览 0 评论 0原文

我有一个正在尝试清理的 Python 库设计,但我注意到其中一部分无法在 Eclipse/PyDev 中自动完成。我很熟悉,这对我来说不是问题,但它是一个其他人最终会使用的库,并且自动完成功能不适用于功能块。

我将快速解释它想要做什么,我重新创建了下面的设计。这一切都有效,但自动完成没有用。也许有人可以纠正我。

在模块 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

在模块 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

在应用程序 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

这样,如果导入了 test_module2.py 模块,就可以通过单独的命名空间成员变量 Main.second 来访问它。将事物分开,如果该模块不可用,那么您将无法访问 Second 的功能。

在 test_module2.py 中,导入了 Main(无论如何你都不能在没有 Main 的情况下使用 Second),并且 _main 默认为 Main。当您处理在构造 Main 并导入 Second 时设置的父 _main 引用时,这允许在 Second 中自动完成。 (这很好)

在 Main 中,Second 是可选的,并且永远不会直接从 Main 方法调用。所以自动完成是没有必要的。 (这很好)

在 __main__ 中,自动完成自然适用于 Main 成员变量和方法,但不适用于 m.second。我不能将 m.second 默认为任何值,因为我最终必须从 test_module.py 导入 test_module2.py 。它是可选的,由 __main__ 的 test_module2.py 导入定义。例如,如果 __main__ 导入 test_module2.py,则 Second 会自动可供应用程序使用。

任何人都有更好的方法来将可选导入的模块/类构造添加到成员变量中,并且可以与 IDE 自动完成一起使用吗?

预先感谢您的任何想法。

我得出的结论是,如果父类继承自类,则使用 PyDev 自动完成功能只会看到设置为类成员的变量,或者将变量默认为类本身。 strong> 例如:

class Main(object):
    second = Second

然后在 __main__ 中,您可以自动完成: main.second...

That 或 Main 必须从 Second 继承。

好吧,我需要回去抱怨这个库设计无法与 IDE 自动完成功能配合使用。看看我是否可以使用包装类来继承 import test_module2 是否存在并清理内容。

我的解决方案: 这是我想到的:

在模块 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__()

在模块 test_module.py

class Main(object):
    _variable = 0
    second = None
    def __init__(self):
        super(Main, self).__init__()

    def print_variable(self):
        print self._variable

现在!在 test.py 中,如果您导入 test_module 或 test_module2 (不是两者),您可以构建具有或不具有 Second 附加功能的 Main。 Second 将有权访问 Main 中的所有内容,并且由于 Main 继承了 Second,因此自动完成功能有效。

在应用程序 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

我不知道是否可以轻松地将 Second 的方法移动到子命名空间中,例如 Main.second.set_variable()。在 Main 将 Second 构造为变量之后,我必须在 Second 中显式设置 Main 引用(在 Main init 中, self.second = Second() ),并且不能让 Second 由 Main 继承。然后,您可以调用 m.second.set_main_variable(10),并使所有 Second 方法都可以从 .second 命名空间下的 Main 访问。

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(object):
    _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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明天过后 2024-12-09 23:04:41

首先,简单胜于复杂 --你的设计似乎毫无理由地复杂。也许您应该提供一些有关您的实际图书馆的详细信息。

其次,Python 作为一种动态类型语言,很自然地会出现 IDE 无法自动完成的情况,因为您的 IDE 具有静态视角。而且您绝对不应该为了适应 IDE 的功能而进行编程。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文