如何将(几乎)对象方法中的所有局部变量设置为该对象的属性?
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
如何将(几乎)对象方法中的所有局部变量设置为该对象的属性?
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
受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
已经有一个python 调试器可以让你检查局部变量,所以用随机实例属性污染对象是没有意义的。
此外,如果多个方法使用相同的局部变量名称,您的方法也不起作用,因为方法可能会覆盖某些实例属性,从而使对象的状态处于模棱两可的状态。
此外,您的解决方案违反了DRY 原则,因为您必须在 every 之前添加代码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 调试器。