为什么__setattr __()在设置成员数组变量元素时不会递归?

时间:2015-01-28 09:48:42

标签: python arrays recursion

不确定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行看到类似的递归原因。

有谁知道这是为什么?感谢...

1 个答案:

答案 0 :(得分:1)

如果我理解正确,看表达本身应该回答你的问题:

self._rowData[bla] = val已解析为

  • self.__getattribute__("_rowData")[bla] = val
  • 然后self.__getattribute__("_rowData").__setitem__(bla, val)

没有进一步调用__setattr__,因为没有设置任何属性,只需更改一个。