Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使带有uu getattr的类可拾取_Python_Python 2.7_Pickle_Getattr - Fatal编程技术网

Python 如何使带有uu getattr的类可拾取

Python 如何使带有uu getattr的类可拾取,python,python-2.7,pickle,getattr,Python,Python 2.7,Pickle,Getattr,如何修改下面的类以使其可拾取 此问题:与之类似,但在使用getattr时出现了错误的异常 这另一个问题似乎提供了有意义的见解,但它没有提供一个例子,老实说,我无法理解我应该实现什么 import pickle class Foo(object): def __init__(self, dct): for key in dct: setattr(self, key, dct[key]) class Bar(object): def __i

如何修改下面的类以使其可拾取

此问题:与之类似,但在使用getattr时出现了错误的异常

这另一个问题似乎提供了有意义的见解,但它没有提供一个例子,老实说,我无法理解我应该实现什么

import pickle
class Foo(object):
    def __init__(self, dct):
        for key in dct:
            setattr(self, key, dct[key])


class Bar(object):
    def __init__(self, dct):
        for key in dct:
            setattr(self, key, dct[key])

    def __getattr__(self, attr):
        """If attr is not in channel, look in timing_data
        """
        return getattr(self.foo, attr)

if __name__=='__main__':
    dct={'a':1,'b':2,'c':3}
    foo=Foo(dct)
    dct2={'d':1,'e':2,'f':3,'foo':foo}
    bar=Bar(dct2)
    pickle.dump(bar,open('test.pkl','w'))
    bar=pickle.load(open('test.pkl','r'))
结果:

     14         """If attr is not in channel, look in timing_data
     15         """
---> 16         return getattr(self.foo, attr)
     17
     18 if __name__=='__main__':

RuntimeError: maximum recursion depth exceeded while calling a Python object

这里的问题是您的
\uuu getattr\uuu
方法实现得很差。它假定存在
self.foo
。如果
self.foo
不存在,尝试访问它会调用
\uuuu getattr\uuuu
——这会导致无限递归:

>>> bar = Bar({})  # no `foo` attribute
>>> bar.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "untitled.py", line 19, in __getattr__
    return getattr(self.foo, attr)
  File "untitled.py", line 19, in __getattr__
    return getattr(self.foo, attr)
  File "untitled.py", line 19, in __getattr__
    return getattr(self.foo, attr)
  [Previous line repeated 329 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
(我使用该函数获取对象的dict,因为它看起来比
self更好


现在一切正常:

dct={'a':1,'b':2,'c':3}
foo=Foo(dct)
dct2={'d':1,'e':2,'f':3,'foo':foo}
bar=Bar(dct2)
data = pickle.dumps(bar)
bar = pickle.loads(data)
print(vars(bar))
# output:
# {'d': 1, 'e': 2, 'f': 3, 'foo': <__main__.Foo object at 0x7f040fc7e7f0>}
dct={'a':1,'b':2,'c':3}
foo=foo(dct)
dct2={'d':1,'e':2,'f':3,'foo':foo}
bar=bar(dct2)
数据=pickle.dumps(bar)
bar=pickle.load(数据)
打印(变量(bar))
#输出:
#{'d':1,'e':2,'f':3,'foo':}

为第一段添加了更多的解释:
\uuuuu getattr\uuuuuu
只有在“常规方法”中找不到属性时才会调用,例如检查对象的
\uuuuu dict\uuuuuu
。这就是为什么
中的
self.foo
不总是给你无限递归,而只是在
目录中找不到
self.foo
时。
dct={'a':1,'b':2,'c':3}
foo=Foo(dct)
dct2={'d':1,'e':2,'f':3,'foo':foo}
bar=Bar(dct2)
data = pickle.dumps(bar)
bar = pickle.loads(data)
print(vars(bar))
# output:
# {'d': 1, 'e': 2, 'f': 3, 'foo': <__main__.Foo object at 0x7f040fc7e7f0>}