Nix*_*Nix 6 python pickle python-2.7
我有一个像类这样的字典,用于存储一些值作为属性.我最近添加了一些logic(__getattr__
),如果属性不存在则返回None.一旦我做了这个泡菜崩溃,我想要了解为什么?
测试代码:
import cPickle
class DictionaryLike(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __iter__(self):
return iter(self.__dict__)
def __getitem__(self, key):
if(self.__dict__.has_key(key)):
return self.__dict__[key]
else:
return None
''' This is the culprit...'''
def __getattr__(self, key):
print 'Retreiving Value ' , key
return self.__getitem__(key)
class SomeClass(object):
def __init__(self, kwargs={}):
self.args = DictionaryLike(**kwargs)
someClass = SomeClass()
content = cPickle.dumps(someClass,-1)
print content
Run Code Online (Sandbox Code Playgroud)
结果:
Retreiving Value __getnewargs__
Traceback (most recent call last):
File <<file>> line 29, in <module>
content = cPickle.dumps(someClass,-1)
TypeError: 'NoneType' object is not callable`
Run Code Online (Sandbox Code Playgroud)
我做了些蠢事吗?我读过一篇帖子,如果一个密钥不存在,deepcopy()可能会要求我抛出异常?如果是这种情况,是否有任何简单的方法来实现我想要的而不抛出异常?
最终结果是,如果有人打电话
someClass.args.i_dont_exist
Run Code Online (Sandbox Code Playgroud)
我希望它返回None.
Fer*_*yer 13
实现__getattr__
有点棘手,因为它是为每个不存在的属性调用的.在您的情况下,pickle
模块测试您的类的__getnewargs__
特殊方法和接收None
,这显然是不可调用的.
您可能希望更改__getattr__
以调用魔术名称的基本实现:
def __getattr__(self, key):
if key.startswith('__') and key.endswith('__'):
return super(DictionaryLike, self).__getattr__(key)
return self.__getitem__(key)
Run Code Online (Sandbox Code Playgroud)
我通常会以下划线开头的所有名称,以便我可以回避内部符号的魔力.
您需要AttributeError
在类中不存在属性时引发:
def __getattr__(self, key):
i = self.__getitem__(key)
if i == None:
raise AttributeError
return self.__getitem__(key)
Run Code Online (Sandbox Code Playgroud)
我将假设这种行为是必需的.从getattr的python文档中,"当一个属性查找没有找到通常位置的属性时调用(即它不是一个实例属性,也不是在类树中找到self).name是属性名称.这个方法应该返回(计算的)属性值或引发AttributeError异常."
除非你提出异常,否则没有办法告诉pickle等找不到它正在寻找的属性.例如,在您的错误消息中,pickle正在寻找一个名为的特殊可调用方法__getnewargs__
,pickle期望如果未找到AttributeError异常,则返回值是可调用的.
我想你周围的一个潜在的工作可能会尝试定义pickle正在寻找的所有特殊方法作为虚拟方法?
归档时间: |
|
查看次数: |
2247 次 |
最近记录: |