【发布时间】:2014-02-01 02:54:53
【问题描述】:
好的,这有点复杂。
假设我的包中有一个模块:
a_package
|-- __init__.py
|-- a_module.py
在a_module.py里面我声明A_Class:
# file location: a_package/a_module.py
class A_Class():
def say(self):
print ("cheese")
我可以创建一个A_Class 的实例并通过这样做调用say 方法:
from a_package.a_module import A_Class
my_object = A_Class()
my_object.say() # this will display 'cheese' as expected
但是,我想做一个更动态的方法(我计划有很多包和类,并且想让代码更容易编写)。所以,我做了一个函数叫load_class
def load_class(package_name, module_name, class_name)
result = None
try:
exec('from ' + package_name + '.' + module_name + ' import ' + class_name)
exec('result = '+class_name)
except:
raise ImportError('Unable to load the class')
return result
# Now, I can conveniently do this:
A_Class = load_class('a_package', 'a_module', 'A_Class')
my_object = A_Class()
my_object.say()
# or even shorter:
load_class('a_package', 'a_module', 'A_Class')().say()
程序按预期运行,但 IDE(我使用 pydev)不理解我的代码,无法进行智能感知(自动补全代码)。
如果我使用第一种方法,智能感知显然是有效的:
from a_package.a_module import A_Class
my_object = A_Class()
my_object. # when I press ".", there will be a popup to let me choose "say" method
但如果我使用第二种方法,智能感知无法为我完成:
load_class('a_package', 'a_module', 'A_Class')(). # when I press ".", nothing happened
我知道,这是在 Python 中动态导入的权衡。但是,我想知道是否有一些替代方法可以让我做第二种方法(可能不使用exec)仍然可以让通用IDE(如Pydev)的智能感知猜测类内的方法?
编辑:为什么我需要这样做? 假设我有这样一个目录结构
fruit
|-- strawberry.py
|-- orange.py
chocolate
|-- cadbury.py
|-- kitkat.py
need_dynamic.py
在need_dynamic.py,我有这个脚本:
food_list = ['fruit', 'chocolate']
subfood_list = [['strawberry', 'orange'],['cadbury', 'kitkat']]
# show food list and ask user to choose food
for i in xrange(len(food_list)):
print i + " : " + food_list[i]
food_index = int(raw_input('chose one'))
# show subfood list and ask user to choose subfood
for i in xrange(len(subfood_list[food_index])):
print i + " : " + subfood_list[food_index][i]
subfood_index = int(raw_input('chose one'))
# init the class
my_class = load_class(food_list[food_index], subfood_list[food_index, subfood_index])
# the rest of the code
这只是为了简化,实际上,我打算通过获取目录来自动填充food_list和subfood_list。
假设您有一个数据分类框架,并希望让用户选择他们想要使用的方法。用户还应该能够通过简单地添加 python 包一个模块来扩展框架。
我希望这个例子是合理的。
再次编辑接受的答案不能解决智能感知问题。但它展示了如何更好地编码。我认为这是IDE问题而不是python问题。我会发布另一个问题。
【问题讨论】:
-
你的方法比
from package.module import klass更好吗?后者更具语义性,不会让其他查看您的代码的程序员感到困惑。 -
正如我所说,我的方法更容易编写。这也让我可以使用配置变量调用不同的方法和类。
-
不要自作聪明。
标签: python intellisense dynamic-import