在模块Foo中我有一个功能:
def register_scheme(class_name,*properties_class):
scheme_class = type(class_name, (Scheme,), dict( _properties_classes={c.__name__:c for c in properties_class} )) # Scheme is another class defined in Foo
globals()[class_name] = scheme_class
在另一个导入Foo的模块中:
foo.register_scheme("ball",color,distance) # color and distance are two classes defined in this module
现在我可以这样做:
ball = foo.ball("color"=red,"distance"=0.5) # __init__ function of Scheme takes care of this, code not shown
代码工作正常,但pydev抱怨红十字说"来自import的未定义变量:ball"。
这是可以预料的。问题是我要注册很多"计划"在我的代码中,导致整个地方出现错误消息。我想这不会产生可怕的后果,但那真的很烦人。
有人会有解决方案吗?
修改
这是我的解决方案,它与我想要的完全不符,但足够接近
def register_scheme(class_name,*properties_class):
#here some code checking if this class name is ok, removed for brevity #
scheme_class = type(class_name, (Scheme,), dict( _properties_classes={c.__name__:c for c in properties_class} ))
Scheme._known_scheme_classes[class_name]=scheme_class # _known_scheme_classes is a class dict of Scheme
def create(scheme_class_name,**values):
# some code checking such class has been registered, removed for brevity #
return Scheme._known_scheme_classes[scheme_class_name](**values)
现在我可以在导入foo的其他模块中执行此操作:
foo.register_scheme("ball",color,distance)
my_ball = foo.create("ball",color="red",distance=0.5)
答案 0 :(得分:1)
Python是一种动态语言,因此静态代码分析器无法反省内容。
在你的情况下,PyDev抱怨foo.ball
是一个“未定义的变量”是绝对正常的,因为ball
中foo
未被定义模块,它在运行时创建。如果没有实际运行程序,Eclipse就不会也不会知道这一点。
一般来说,拥有这种魔力是个坏主意。
你的代码中有这个:
globals()[class_name] = scheme_class
所以你动态创建一个类而不验证它是否已经创建,然后将其注入globals
。
然后会建议你而不是注射它只是返回它:
def crate_scheme(class_name, *properties_class):
scheme_class = type(class_name, (Scheme,), dict( _properties_classes={c.__name__:c for c in properties_class} )) # Scheme is another class defined in Foo
return scheme_class
然后你会在另一个模块中做:
Ball = foo.create_scheme("ball", color, distance) # color and distance are two classes defined in this module
ball = Ball("color"=red, "distance"=0.5) # __init__ function of Scheme takes care of this, code not shown
这应该有助于摆脱PyDev抱怨,但是如果可能的话,应该避免动态创建类:explicit比隐式(import this
)更好。
在这里使用构图而不是继承。