python 中导入类的范围是什么?

发布于 2024-07-06 01:46:29 字数 988 浏览 6 评论 0原文

请原谅模糊的标题。 如果有人有建议,请告诉我! 还请重新标记更合适的标签!

问题

我希望导入类的实例能够查看导入器范围(全局、局部)中的内容。 由于我不确定这里起作用的确切机制,因此我可以用片段比文字更好地描述它。

## 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()')

此类任务是否有常见的习惯用法/模式? 我是不是完全找错了树?

Please excuse the vague title. If anyone has a suggestion, please let me know! Also please retag with more appropriate tags!

The Problem

I want to have an instance of an imported class be able to view things in the scope (globals, locals) of the importer. Since I'm not sure of the exact mechanism at work here, I can describe it much better with snippets than words.

## 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())

Then run this code from an iteractive session, there there will be lots of 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()')

Is there a common idiom / pattern for this sort of task? Am I barking up the wrong tree entirely?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌上青苔 2024-07-13 01:46:29

在此示例中,您可以简单地将函数作为对象传递给 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!

一些注释

  1. 在这里,我们将 file1 中的所有对象插入此模块的命名空间
  2. f2 不在以下命名空间中file1,因此我们得到一个NameError
  3. 现在我们显式地传递环境,并且可以评估代码
  4. f1 位于该模块的命名空间中,因为我们导入了它

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

In this example, you can simply hand over functions as objects to the methods in C1:

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

In Python, you can pass functions and classes to other methods and invoke/create them there.

If you want to actually evaluate a code string, you have to specify the environment, as already mentioned by Thomas.

Your module from above, slightly changed:

## 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)

Now, in the interactive interpreter:

>>> 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!

Some annotations

  1. Here, we insert all objects from file1 into this module's namespace
  2. f2 is not in the namespace of file1, therefore we get a NameError
  3. Now we pass the environment explictly, and the code can be evaluated
  4. f1 is in the namespace of this module, because we imported it

Edit: Added code sample on how to explicitly pass environment for eval.

躲猫猫 2024-07-13 01:46:29

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

您可以做两件事:显式传递您希望他们使用的“环境”,或者使用堆栈黑客来访问调用者的名称空间。 前者比后者更受青睐,因为它不像后者那样依赖于实现且脆弱。

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

Functions are always executed in the scope they are defined in, as are methods and class bodies. They are never executed in another scope. Because importing is just another assignment statement, and everything in Python is a reference, the functions, classes and modules don't even know where they are imported to.

You can do two things: explicitly pass the 'environment' you want them to use, or use stack hackery to access their caller's namespace. The former is vastly preferred over the latter, as it's not as implementation-dependent and fragile as the latter.

You may wish to look at the string.Template class, which tries to do something similar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文