代码之家  ›  专栏  ›  技术社区  ›  Gregg Lind

python中导入类的作用域是什么?

  •  2
  • Gregg Lind  · 技术社区  · 16 年前

    请原谅这个模糊的标题。如果有人有什么建议,请告诉我!另外,请重新标记更合适的标签!

    ## File 1
    def f1():  print "go f1!"
    
    class C1(object):
        def do_eval(self,x):  # maybe this should be do_evil, given what happens
            print "evaling"
            eval(x)
            eval(x,globals(),locals())
    

    然后从一个实际会话中运行这段代码,将会有很多 NameErrors

    ## interactive
    class C2(object):
        def do_eval(self,x):  # maybe this should be do_evil, given what happens
            print "evaling"
            eval(x)
            eval(x,globals(),locals())
    
    def f2():
        print "go f2!"
    
    from file1 import C1
    import file1
    
    C1().do_eval('file1.f1()')
    C1().do_eval('f1()')
    C1().do_eval('f2()')
    
    file1.C1().do_eval('file1.f1()')
    file1.C1().do_eval('f1()')
    file1.C1().do_eval('f2()')
    
    C2().do_eval('f2()')
    C2().do_eval('file1.f1()')
    C2().do_eval('f1()')
    

    2 回复  |  直到 16 年前
        1
  •  2
  •   Torsten Marek    16 年前

    在本例中,您可以简单地将函数作为对象移交给中的方法 C1

    >>> class C1(object):
    >>>    def eval(self, x):
    >>>        x()
    >>>
    >>> def f2(): print "go f2"
    >>> c = C1()
    >>> c.eval(f2)
    go f2
    

    在Python中,您可以将函数和类传递给其他方法并在那里调用/创建它们。

    从上面看,您的模块略有更改:

    ## File 1
    def f1():  print "go f1!"
    
    class C1(object):
        def do_eval(self, x, e_globals = globals(), e_locals = locals()):
            eval(x, e_globals, e_locals)
    

    >>> def f2():
    >>>    print "go f2!"
    >>> from file1 import *    # 1
    >>> C1().do_eval("f2()")   # 2
    NameError: name 'f2' is not defined
    
    >>> C1().do_eval("f2()", globals(), locals()) #3
    go f2!
    >>> C1().do_eval("f1()", globals(), locals()) #4
    go f1!
    

    一些注释

    1. file1 进入此模块的命名空间
    2. f2 不在的命名空间中 文件1 ,因此我们得到一个 NameError
    3. 现在,我们明确地传递了环境,并且可以对代码进行评估
    4. f1 在这个模块的命名空间中,因为我们导入了它

    编辑 :添加了关于如何显式传递的环境的代码示例 eval .

        2
  •  1
  •   Thomas Wouters    16 年前

    函数总是在其定义的范围内执行,方法和类主体也是如此。它们永远不会在另一个作用域中执行。因为导入只是另一个赋值语句,Python中的所有内容都是引用,所以函数、类和模块甚至不知道导入到哪里。

    您可以做两件事:显式地传递您希望他们使用的“环境”,或者使用stack hackery访问调用者的命名空间。前者比后者更受欢迎,因为它不像后者那样依赖于实现和脆弱。