-1

如何将(几乎)对象方法中的所有局部变量设置为该对象的属性?

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
4

2 回答 2

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
于 2013-02-07T18:24:01.857 回答
-1

已经有一个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 调试器。

于 2013-02-08T08:48:58.907 回答