我正在开展一个项目,处理抽象数学意义上的函数。如果没有让读者厌烦细节,我会说我在早期版本中有以下结构:
private static void ClearChunkVB(Vector2 PchunkXZ)
{
VBContainer thisChunk;
int j;
thisChunk = Landscape.chunkVB[(int)PchunkXZ.X, (int)PchunkXZ.Y];
if (thisChunk.voxelVB.Count > 0)
{
for (j = 0; j < thisChunk.voxelVB.Count; ++j)
{
thisChunk.voxelVB[j].VertCount = 0;
VBPoolManager.DestroyVB(thisChunk.voxelVB[j]);
}
thisChunk.voxelVB.Clear();
}
}
当然,这并不是我对class Foo(Bar):
def __init__(self, a, b):
self.a = a
self.b = b
self.sub_unit = Foo(a, not b)
的参数做出的改变,但足以说明,如果重复访问此属性,则必须导致{{无限长链'。 1}}对象。显然,当一个实例化Foo
时,这会导致无限递归。我在早期版本中通过删除Foo
的最后一行并将以下内容添加到Foo
类来解决了这个问题:
init
这非常有效,因为我可以根据需要计算链中的下一个对象。
在查看代码时,我意识到由于其他原因,我需要Foo
的实例,而不是它的子类。要查看我是否可以覆盖单个实例的def __getattr__(self, attr: str):
if attr == 'sub_unit':
return Foo(self.a, not self.b)
else:
return super().__getattr__(attr)
,我尝试了以下内容:
Bar
这里发生了什么,我不明白?为什么getattr
没有调用>>> foo = Bar(a=1, b=2) # sub_unit doesn't get set here.
>>> foo.__getattr__ = lambda attr: 'foo'
>>> foo.a
1
>>> foo.__getattr__('a')
'foo'
?
是否有一种方法可以为单个实例覆盖foo.a
,或者我最好的选择是将我读取的所有代码foo.__getattr__('a')
和朋友称为函数调用处理这个特例?
答案 0 :(得分:1)
当您使用foo.a查找属性a
时,python会在实例的属性字典中查找它。如果找不到,则会调用__getattr__
方法。
相反,如果实例中存在a
,则不会调用__getattr__
。