如何将(几乎)对象方法中的所有局部变量设置为该对象的属性?
class Obj(object):
def do_something(self):
localstr = 'hello world'
localnum = 1
#TODO store vars in the object for easier inspection
x = Obj()
x.do_something()
print x.localstr, x.localnum
答案 0 :(得分:0)
受到Python update object from dictionary的启发,我想出了以下内容:
class Obj(object):
def do_something(self):
localstr = 'hello world'
localnum = 1
# store vars in the object for easier inspection
l = locals().copy()
del l['self']
for key,value in l.iteritems():
setattr(self, key, value)
x = Obj()
x.do_something()
print x.localstr, x.localnum
答案 1 :(得分:-1)
已经有python debugger允许您检查局部变量,因此使用随机实例属性污染对象没有意义。
如果多个方法使用相同的局部变量名,您的方法也不起作用,因为方法可能会覆盖某些实例属性,使对象的状态处于模糊状态。
此外,您的解决方案违反了DRY principle,因为您必须在每return
之前添加代码。
另一个缺点是,在方法执行期间,您通常想要在多个位置知道局部变量的状态,这对您的答案是不可能的。
如果你真的想手动保存本地变量,那么这样的事情可能比你的解决方案好得多:
import inspect
from collections import defaultdict
class LogLocals(object):
NO_BREAK_POINT = object()
def __init__(self):
self.__locals = defaultdict(defaultdict(list))
def register_locals(self, local_vars, method_name=None,
break_point=NO_BREAK_POINT):
if method_name is None:
method_name = inspect.currentframe(1).f_code.co_name
self.__locals[method_name][break_point].append(local_vars)
def reset_locals(self, method_name=None, break_point=NO_BREAK_POINT,
all_=False):
if method_name is None:
method_name = inspect.currentframe(1).f_code.co_name
if all_:
del self.__locals[method_name]
else:
del self.__locals[method_name][point]
def get_locals(self, method_name, break_point=NO_BREAK_POINT):
return self.__locals[method_name][break_point]
您只需继承它并在想要保存状态时调用register_locals(locals())
。它还允许区分“断点”,最重要的是它不会污染实例。
它还区分不同的调用返回list
个状态而不是最后一个状态。
如果您想通过属性访问某些呼叫的本地人,您可以执行以下操作:
class SimpleNamespace(object): # python3.3 already provides this
def __init__(self, attrs):
self.__dict__.update(attrs)
the_locals = x.get_locals('method_1')[-1] # take only last call locals
x = SimpleNamespace(the_locals)
x.some_local_variable
无论如何,我相信这没什么用处。你应该使用python调试器。