Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中导入类的作用域是什么?_Python_Import_Scope_Eval - Fatal编程技术网

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

python中导入类的作用域是什么?,python,import,scope,eval,Python,Import,Scope,Eval,请原谅这个模糊的标题。如果有人有什么建议,请告诉我!另外,请重新标记更合适的标签 问题 我希望有一个导入类的实例能够查看导入器范围(全局、局部)中的内容。由于我不确定具体的工作机制,我可以用片段而不是文字来描述它 ## File 1 def f1(): print "go f1!" class C1(object): def do_eval(self,x): # maybe this should be do_evil, given what happens pri

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

问题

我希望有一个导入类的实例能够查看导入器范围(全局、局部)中的内容。由于我不确定具体的工作机制,我可以用片段而不是文字来描述它

## 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())
然后从iTreactive会话运行此代码,将出现大量
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()')

这类任务是否有共同的习惯用法/模式?我是不是找错人了

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

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


您可能希望查看string.Template类,它尝试执行类似的操作。

在本例中,您只需将函数作为对象移交给
C1
中的方法即可:

>>> class C1(object):
>>>    def eval(self, x):
>>>        x()
>>>
>>> def f2(): print "go f2"
>>> c = C1()
>>> c.eval(f2)
go f2
在Python中,您可以将函数和类传递给其他方法并在那里调用/创建它们

如果要实际计算代码字符串,必须指定环境,正如Thomas已经提到的那样

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

## 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!
一些注释
  • 在这里,我们将
    file1
    中的所有对象插入该模块的名称空间
  • f2
    不在
    file1
    的命名空间中,因此我们得到一个
    namererror
  • 现在,我们明确地传递了环境,并且可以对代码进行评估
  • f1
    位于此模块的命名空间中,因为我们导入了它

  • Edit:添加了关于如何显式传递环境以进行
    eval

    的代码示例,您希望实现什么?如果只传递函数而不是完整表达式,那么可能有更简单的方法。Torsten,我想看看一个解决方案,其中函数也会被抛出。基于你的问题,这看起来肯定是“不和谐的”,也许我需要再仔细考虑一下。实际的项目是一个交互式的虚构框架及其解析器。感谢您添加了这个框架,您对注释的解释已经足够好了。大多数情况下,我也喜欢看到其他的方法。我希望这能让它更清楚一点!对不起,我弄糊涂了。