不确定SO是否是正确的地方,但是这里......
我一直在学习__setattr__()
和__getattr__()
并且感觉我理解了各种递归危险,除了在类实例数组变量中的元素被设置为没有'在这种情况下,t似乎是递归。
class Test(object):
tableInfo = { 'table1' : {'col1' : 0, 'col2':1} }
def __init__(self, tableName):
super(Test, self).__setattr__('_tableName', tableName) # Must be set this way to stop infinite recursion as attribute is accessed in bot set and get attr
self._rowData = [123, 456]
def __getattr__(self, name):
print "# GETTING %s" % (name)
assert self._tableName in Test.tableInfo
if name in Test.tableInfo[self._tableName]:
return self._rowData[Test.tableInfo[self._tableName][name]]
else:
raise AttributeError()
def __setattr__(self, name, val):
print "# SETTING %s" % (name)
if name in Test.tableInfo[self._tableName]:
print "Table column name found"
self._rowData[Test.tableInfo[self._tableName][name]] = val
self._someAttr = 1
else:
super(Test, self).__setattr__(name, val)
class Table1(Test):
def __init__(self, *args, **kwargs):
super(Table1, self).__init__("table1", *args, **kwargs)
t = Table1()
print t.col1
print t.col2
t.col1 = 999
print t.col1
t.dummy = 101
我正在玩的例子粘贴在下面:
$ python test.py
# SETTING _rowData
# GETTING col1
123
# GETTING col2
456
# SETTING col1
Table column name found
# SETTING _someAttr
# GETTING col1
999
# SETTING dummy
我可以看到设置col1
导致递归回到__setattr__()
,正如我期望的那样,由于行self._someAttr = 1
。
我不明白为什么我不会在self._rowData[Test.tableInfo[self._tableName][name]] = val
行看到类似的递归原因。
有谁知道这是为什么?感谢...
答案 0 :(得分:1)
如果我理解正确,看表达本身应该回答你的问题:
self._rowData[bla] = val
已解析为
self.__getattribute__("_rowData")[bla] = val
self.__getattribute__("_rowData").__setitem__(bla, val)
没有进一步调用__setattr__
,因为没有设置任何属性,只需更改一个。