我发现自己正在编写以下代码:
def dlt(translation):
del translation.strands[translation.active][translation.locus]
我更喜欢这样的东西:
def dlt(translation):
*something*(translation):
del strands[active][locus]
有没有一种方法可以实现这个?
我发现自己正在编写以下代码:
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()
,如this answer所示。
以下代码可以实现这个功能:
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]
在while
块中,translation.__dict__
中的所有项目都可以全局使用。
请注意,这不是线程安全的,并且可能会给未来尝试阅读使用此代码的人(包括您自己)带来很多困惑。个人而言,我不会使用这个。
你应该使用Martijn的答案。但是如果你真的想要做你所问的事情,我认为这个(未经测试的)代码片段可以实现:
exec "del strands...", translation.__dict__
如果你不喜欢这个:那很好,说明你有品味。 :-)
这里还有另一个选项:
def within(obj, func):
return func(**obj.__dict__)
这样调用:
def dostuff(strands, active, locus, **ignored):
del ...
within(translation, dostuff)
__dict__
感觉可能会引起一些麻烦。 - Michael Pankov
__exit__
中,你应该迭代ns
而不是对象命名空间,因为后者可能已经在此期间发生了更改。显然,这样做需要一些小心谨慎。 - Jamey Sharpglobals()
命名空间也可能已经发生了变化;我已经更新了清理代码,以考虑新名称可能已添加到命名空间对象中。 - Martijn Pietersglobals()
中,而这些名称并不存在于你想要保留的命名空间对象中。 :-) 这些问题表明这确实是一种很巧妙的方法。你可能需要跟踪你已经添加的名称。更新答案以解决这个问题。 - Martijn Pieters