如何选择性地导入/构造类到支持 IDE 自动完成的成员变量
我有一个正在尝试清理的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,简单胜于复杂 --你的设计似乎毫无理由地复杂。也许您应该提供一些有关您的实际图书馆的详细信息。
其次,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.