python 中导入类的范围是什么?
请原谅模糊的标题。 如果有人有建议,请告诉我! 还请重新标记更合适的标签!
问题
我希望导入类的实例能够查看导入器范围(全局、局部)中的内容。 由于我不确定这里起作用的确切机制,因此我可以用片段比文字更好地描述它。
## 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在此示例中,您可以简单地将函数作为对象传递给 C1 中的方法:
在 Python 中,您可以将函数和类传递给其他方法并在其中调用/创建它们。
如果您想实际评估代码字符串,则必须指定环境,正如 Thomas 已经提到的那样。
上面的模块略有变化:
现在,在交互式解释器中:
一些注释
file1
中的所有对象插入此模块的命名空间f2
不在以下命名空间中file1
,因此我们得到一个NameError
f1
位于该模块的命名空间中,因为我们导入了它编辑:添加了有关如何显式传递
eval
环境的代码示例。In this example, you can simply hand over functions as objects to the methods in
C1
: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:
Now, in the interactive interpreter:
Some annotations
file1
into this module's namespacef2
is not in the namespace offile1
, therefore we get aNameError
f1
is in the namespace of this module, because we imported itEdit: Added code sample on how to explicitly pass environment for
eval
.函数始终在其定义的范围内执行,方法和类体也是如此。 它们永远不会在另一个作用域中执行。 因为导入只是另一个赋值语句,而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.