获取要在 with 语句中执行的命令块 [英] Getting the block of commands that are to be executed in the with statement

查看:65
本文介绍了获取要在 with 语句中执行的命令块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读 with 声明的规范时(link),我有一些东西想玩.这不适用于任何生产代码或任何东西,我只是在探索,所以如果这是一个坏主意,请不要太苛刻.

In reading the specifications for the with statement (link), I have some things I'd like to play around with. This isn't for any production code or anything, I'm just exploring, so please don't be too harsh if this is a bad idea.

我想做的是获取上面链接文档中名为BLOCK"的部分,并在对 __enter__ 的调用中实际修改它.(请参阅链接的文档,就在动机和摘要部分开始之后.)

What I'd like to do is grab the piece called "BLOCK" in the linked docs above, and actually tinker around with it inside of the call to __enter__. (See the linked doc, just after the start of the motivation and summary section.)

这个想法是创建我自己的一种动态本地命名空间.像这样:

The idea is to create my own sort of on-the-fly local namespace. Something like this:

with MyNameSpace(some_object):
    print a #Should print some_object.a
    x = 4 #Should set some_object.x=4

基本上,我希望 with 块内的语句从属于 some_object 的局部变量和赋值约定.

Basically, I want the statements inside of the with block to be subordinate to the local variables and assignment conventions of some_object.

在我的特定情况下,some_object 可能是一个特殊的数据数组,它具有我自己的按列操作之类的东西.在这种情况下,如 x = y + 5 if y >4 else y - 2 在幕后可能是一些奇特的 NumPy 向量化操作,但我不需要显式调用 some_object 的接口到这些方法.在命名空间中,表达式应该正常工作"(但是我将它们定义为在 MyNameSpace 类中推断.

In my specific case, some_object might be a special data array that has my own column-wise operations or something. In which case saying something like x = y + 5 if y > 4 else y - 2 might be some fancy NumPy vectorized operation under the hood, but I don't need to explicitly call some_object's interface to those methods. In the namespace, the expressions should "just work" (however I define them to be inferred in the MyNameSpace class.

我的第一个想法是以某种方式中断 with 进程并获取进入 try 块中的代码.然后在 __enter__ 被调用时解释该代码,并用其他东西替换 try 块中的代码(也许 pass 如果可以,但是可能是将 some_object 恢复到原始变量范围并保留其新更改的变量的东西).

My first idea is to somehow interrupt the with process and get a hold of the code that goes in the try block. Then interpret that code when __enter__ gets called, and replace the code in the try block with something else (perhaps pass if that would work, but possibly something that restores some_object back to the original variable scope with its new changed variables preserved).

一个简单的测试用例是这样的:

A simple test case would be something like this:

my_dict = {'a':3, 'b':2}
with MyNameSpace(my_dict):
    print a # Should print 3
    x = 5 # When the block finishes, my_dict['x'] should now be 5

我很感兴趣这个想法是否已经存在.

I'm interested if this idea exists somewhere already.

我知道分配变量的最佳实践.这是一个宠物项目,所以请假设,仅仅为了这个想法,我们可以忽略最佳实践.即使您不喜欢以这种方式分配变量,它在我当前的项目中也很有用.

I am aware of best practices things for assigning variables. This is a pet project, so please assume that, just for the sake of this idea, we can ignore best practices. Even if you wouldn't like assigning variables this way, it could be useful in my current project.

编辑

为了澄清我可能想要做的棘手事情的种类,并解决下面声称无法完成的答案,请考虑下面的示例文件 testLocals.py:

To clarify the kinds of tricky stuff I might want to do, and to address the answer below claiming that it can't be done, consider the example file testLocals.py below:

my_dict = {'a':1, 'b':2}
m = locals()
print m["my_dict"]['a']
m["my_dict"]['c'] = 3
print my_dict

class some_other_scope(object):
    def __init__(self, some_scope):
        x = 5
        g = locals()
        some_scope.update(g)
        some_scope["my_dict"]["d"] = 4

sos = some_other_scope(m)
print my_dict
print x

当我以非交互方式运行它时会给出以下内容:

which gives the following when I run it non-interactively:

ely@AMDESK:~/Desktop/Programming/Python$ python testLocals.py
1
{'a': 1, 'c': 3, 'b': 2}
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
5

推荐答案

试试这个.

import sys 
class MyNameSpace(object):
    def __init__(self,ns):
        self.ns = ns
    def __enter__(self):
        globals().update(self.ns)
    def __exit__(self, exc_type,exc_value,traceback):
        self.ns.update(sys._getframe(1).f_locals)

my_dict = {'a':3, 'b':2} 
with MyNameSpace(my_dict) as ns:
    print(a) # Should print 3
    x = 5 # When the block finishes, my_dict['x'] should now be 5 

print(my_dict['x'])

这篇关于获取要在 with 语句中执行的命令块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆