[英]How to resolve a global variable in a module?
I have a script as follows 我有一个脚本如下
from mapper import Mapper
class A(object):
def foo(self):
print "world"
a = A()
a.foo()
Mapper['test']()
with Mapper
defined in the file mapper.py
: 使用
mapper.py
文件中定义的Mapper
:
Mapper = {'test': a.foo}
where I want to define a function call referencing an object not defined in mapper.py
, but in the original code. 我想在哪里定义一个函数调用,引用一个未在
mapper.py
定义的对象,但在原始代码中。 However the code above gives the error 但是上面的代码给出了错误
NameError: name 'a' is not defined
which makes kind of sense, as a
is not defined in mapper.py
itself. 这使得那种感觉,作为
a
没有定义mapper.py
本身。 However, is it possible to change the code to let the code do the name resolution in the main code itself, or by the use of globals
or something? 但是,是否可以更改代码以使代码在主代码本身中执行名称解析,或者使用
globals
或其他东西?
To solve this problem I could specify the implementation in mapper.py
as a text and use eval
in the main code, but I would like to avoid the usage of eval
. 为了解决这个问题,我可以将
mapper.py
的实现指定为文本,并在主代码中使用eval
,但我想避免使用eval
。
Additional information: 附加信息:
mapper.py
mapper.py
a
is, or from what clas it is instantiated. a
是,或什么CLAS它被实例化。 Barring security holes like eval
, it's not possible to use a name a
in mapper.py
unless the name is either defined somewhere in mapper.py
or imported from another module. 除非像
eval
这样的安全漏洞,否则无法在mapper.py
使用名称a
,除非该名称在mapper.py
某处定义或从其他模块导入。 There is no way to just let mapper.py
automatically and silently access a value a
from a different module. 没有办法让
mapper.py
自动并静默地访问来自不同模块的值a
。
In addition, if you're using it just in a dict as in your example, a.foo
is going to be evaluated as soon as the dict is created. 另外,如果你只是在你的例子中的dict中使用它,
a.foo
将在创建dict时立即进行评估。 It's not going wait until you actually call the function; 它不会等到你实际调用该函数; as soon as it evaluates
a.foo
to create the dict, it will fail because it doesn't know what a
is. 只要它计算
a.foo
创建字典,它会失败,因为它不知道是什么a
是。
You could get around this second problem by wrapping the element in a function (using a lambda for brevity): 您可以通过将元素包装在函数中来解决第二个问题(为简洁起见使用lambda):
Mapper = {'test': lambda: a.foo}
. 。 .
。 .
。 but this still won't help unless you can somehow get
a
to be available inside mapper.py
. 但这仍然不会帮助,除非你能以某种方式得到
a
可用的内部mapper.py
。
One possibility is to parameterize your Mapper
by the "mystery" object and then pass that object in from outside: 一种可能性是通过“神秘”对象对
Mapper
进行参数化,然后从外部传递该对象:
# mapper.py
Mapper = {'test': lambda a: a.foo}
# other module
from mapper import Mapper
Mapper['test'](a)()
Or, similar to what mgilson
suggested, you could "register" the object a
with Mapper
somehow. 或者,类似于
mgilson
建议的,你可以用Mapper
以某种方式“注册”对象a
。 This lets you pass the object a
only once to register it, and then you don't have to pass it for every call: 这使您可以传递对象
a
唯一的一次注册,然后你不必把它传递每一个呼叫:
# mapper.py
Mapper = {'test': lambda a: Mapper['a'].foo}
# other module
from mapper import Mapper
Mapper['a'] = a
Mapper['test']()()
Note the two sets of parentheses at the end there: one set to evaluate the lambda and extract the function you want to call, and the second set to actually call that function. 注意那里的两组括号:一组用于评估lambda并提取你想要调用的函数,另一组用于实际调用该函数。 You could do a similar deal by, instead of using
Mapper['a']
as the reference, using a module-level variable: 您可以使用模块级变量执行类似的处理,而不是使用
Mapper['a']
作为引用:
# mapper.py
Mapper = {'test': lambda: a.foo}
# other module
import mapper
Mapper = mapper.Mapper
mapper.a = a
Mapper['test']()()
Note that this requires you to do import mapper
in order to set the module variable in that other module. 请注意,这需要您执行
import mapper
以便在该其他模块中设置模块变量。
You could streamline this somewhat by using a custom class for Mapper
instead of a regular dict, and having that class do some work in its __getitem__
to look in a "known location" (eg, read some module variable) to use as a base for evaluating a
. 您可以通过使用
Mapper
的自定义类而不是常规字典来简化这一点,并让该类在其__getitem__
执行一些工作以查看“已知位置”(例如,读取某个模块变量)以用作基础评估a
。 That would be a heavier-weight solution though. 不过,这将是一个更重的解决方案。
The bottom line is that you simply cannot (again, without the use of eval
or other such holes) write code in mapper.py
that uses an undefined variable a
, and then define a variable a
in another module and have mapper.py
automatically know about that. 底线是你根本不能(再次,没有使用
eval
或其他这样的漏洞)在mapper.py
中编写使用未定义变量a
,然后在另一个模块中定义变量a
并让mapper.py
自动知道关于那个。 There has to be some line of code somewhere that "tells" mapper.py
what value of a
you want it to use. 必须有一些代码行,某处“讲述”
mapper.py
什么价值a
你想使用它。
I'm not sure I completely follow, but a
could "register" it's method with Mapper
from anywhere which has a reference to Mapper: 我不知道我完全跟随,而是
a
可以“注册”这是法Mapper
由具有参考映射器的任何地方:
#mapping.py
Mapper = {}
and then: 接着:
#main.py
from mapping import Mapper
#snip
a = A()
Mapper['test'] = a.foo #put your instance method into the Mapper dict.
#snip
Mapper['test']()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.