好吧,这有点复杂。
假设我在包中有一个模块:
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问题。我会发布另一个问题。