有没有办法在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函数必须接受并忽略其他关键字参数的原因。