我正在编写自己的容器,它需要通过属性调用来访问内部的字典。容器的典型用法如下:
dict_container = DictContainer()
dict_container['foo'] = bar
...
print dict_container.foo我知道写这样的东西可能很愚蠢,但这就是我需要提供的功能。我正在考虑通过以下方式实现这一点:
def __getattribute__(self, item):
try:
return object.__getattribute__(item)
except AttributeError:
try:
return self.dict[item]
except KeyError:
print "The object doesn't have such attribute"我不确定嵌套的try/except块是否是一个好的实践,所以另一种方法是使用hasattr()和has_key()
def __getattribute__(self, item):
if hasattr(self, item):
return object.__getattribute__(item)
else:
if self.dict.has_key(item):
return self.dict[item]
else:
raise AttributeError("some customised error")或者使用其中的一个和一个try catch块,如下所示:
def __getattribute__(self, item):
if hasattr(self, item):
return object.__getattribute__(item)
else:
try:
return self.dict[item]
except KeyError:
raise AttributeError("some customised error")哪种选择是最有Pythonic风格和优雅的?
发布于 2013-06-10 07:46:45
您的第一个示例完全正确。即使是官方的Python文档也推荐这种称为EAFP的样式。
就我个人而言,我更喜欢在不必要的时候避免嵌套:
def __getattribute__(self, item):
try:
return object.__getattribute__(item)
except AttributeError:
pass # Fallback to dict
try:
return self.dict[item]
except KeyError:
raise AttributeError("The object doesn't have such attribute") from NonePS。has_key()在Python2中已经被弃用了很长一段时间,请改用item in self.dict。
发布于 2013-06-10 07:46:12
虽然在Java语言中使用异常进行流控制确实是一种糟糕的做法(主要是因为异常迫使虚拟机收集资源(more here)),但在Python语言中有两个重要的原则:duck typing和EAFP。这基本上意味着鼓励您尝试以您认为的方式使用对象,并在事情不是这样时进行处理。
总而言之,唯一的问题是你的代码缩进太多了。如果你喜欢,试着简化一些嵌套,就像lqc在the suggested answer above中建议的那样。
发布于 2013-06-10 07:46:00
对于您的特定示例,您实际上不需要嵌套它们。如果try块中的表达式成功,则函数将返回,因此,只有在第一次尝试失败时,才会运行整个try/except块之后的所有代码。所以你可以这样做:
def __getattribute__(self, item):
try:
return object.__getattribute__(item)
except AttributeError:
pass
# execution only reaches here when try block raised AttributeError
try:
return self.dict[item]
except KeyError:
print "The object doesn't have such attribute"嵌套它们并不坏,但我觉得让它保持扁平会使结构更清晰:您将按顺序尝试一系列内容,然后返回第一个有效的内容。
顺便说一句,您可能需要考虑是否真的希望在这里使用__getattribute__而不是__getattr__。使用__getattr__将会简化事情,因为您将知道正常的属性查找过程已经失败。
https://stackoverflow.com/questions/17015230
复制相似问题