代码之家  ›  专栏  ›  技术社区  ›  Vince

Pydev/eclipse:无法识别动态创建的类

  •  0
  • Vince  · 技术社区  · 11 年前

    在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 I的另一个模块中:

    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)
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   warvariuc    11 年前

    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的抱怨,但无论如何,如果可能的话,应该避免动态创建类:显式优于隐式( import this ).

    此处使用组合而不是继承。