有没有办法在Python中输入类名称空间?

有没有办法在Python中输入类名称空间?,python,class,namespaces,Python,Class,Namespaces,我发现自己正在编写以下代码: def dlt(translation): del translation.strands[translation.active][translation.locus] 我更喜欢这样的东西: def dlt(translation): *something*(translation): del strands[active][locus] 有没有办法做到这一点?名称空间只是Python对象,您可以将对象(包括属性查找的结果)分配给

我发现自己正在编写以下代码:

def dlt(translation):
    del translation.strands[translation.active][translation.locus]
我更喜欢这样的东西:

def dlt(translation):
    *something*(translation):
        del strands[active][locus]

有没有办法做到这一点?

名称空间只是Python对象,您可以将对象(包括属性查找的结果)分配给局部变量名:

strands = translation.strands
active = translation.active
locus = translation.locus
或者,您必须拼凑一个上下文管理器来修改
locals()
,如中所示

像这样的东西可以做到:

import inspect

class Namespace(object):
    def __init__(self, namespaced):
        self.namespaced = namespaced

    def __enter__(self):
        """store the pre-contextmanager scope"""
        ns = globals()
        namespaced = self.namespaced.__dict__
        # keep track of what we add and what we replace
        self.scope_added = namespaced.keys()
        self.scope_before = {k: v for k, v in ns.items() if k in self.scope_added}
        globals().update(namespaced)
        return self

    def __exit__(self):
        ns = globals()
        # remove what we added, then reinstate what we replaced
        for name in self.scope_added:
            if name in ns:
                del ns[name]
        ns.update(self.scope_before)
然后像这样使用它:

with Namespace(translation):
     del strands[active][locus]
def dostuff(strands, active, locus, **ignored):
    del ...
within(translation, dostuff)
其中,
translation.\uuuu dict\uuuu
中的所有项目在
while
块中全局可用


请注意,这是非线程安全的,并且可能会给将来试图阅读使用此功能的代码的任何人(包括您自己)带来很多困惑。就个人而言,我不会用这个。

你可能应该用Martijn的答案。但如果你真的想做你要求的事情,我认为这个(未经测试的)片段可以做到:

exec "del strands...", translation.__dict__
如果你不喜欢:好,你有品味。:-)

还有一个选择:

def within(obj, func):
    return func(**obj.__dict__)
可以这样称呼:

with Namespace(translation):
     del strands[active][locus]
def dostuff(strands, active, locus, **ignored):
    del ...
within(translation, dostuff)

谢谢实际上,我正在寻找一种解决方案,它不需要我手工编写所有作业,所以我可能会尝试你建议的破解方法。@Constantius:我已经用一种适合你的破解方法更新了我的答案。不过这是一个黑客。上下文管理器是一个可爱的黑客!我认为在
\uuuu exit\uuuu
中,您应该迭代
ns
,而不是对象名称空间,因为后者可能同时发生了变化。显然,安全地这样做需要一些小心。@JameySharp:globals()的
globals()名称空间也可能发生了变化;我已经更新了清理,以考虑到新名称也可以添加到名称空间对象中。你是对的,两者都可以更改。嗯。。。我更关心的是从名称空间对象中删除的名称。我想您需要在进入时保存名称空间键集的副本,然后在退出时删除该集中的所有键,然后从保存的全局更新全局。如果两者的名称相同,则该顺序将恢复原始值。这是我在提出问题后思考的问题。不过我喜欢它:它有什么陷阱吗?触摸
\uuuu dict\uuuu
感觉可能会引起一些麻烦。主要的陷阱是你会得到你不知道你的对象拥有的字段。除了字段之外,还将传递方法和其他各种通常不可见的内容。这就是样例dostuff函数必须接受并忽略其他关键字参数的原因。