【问题标题】:Odd behaviour of python's class [duplicate]python类的奇怪行为[重复]
【发布时间】:2011-11-16 02:36:04
【问题描述】:

这是一个python类:

class TxdTest(object):
    def __init__(self, name = '', atrributes = []):
        self.name = name
        self.attributes = atrributes

然后我像这样使用它:

def main():
    for i in range(3):
        test = TxdTest()
        print test.name
        print test.attributes
        test.name = 'a'
        test.attributes.append(1)

那么,结果如何?结果是:

[]

[1]

[1, 1]

为什么类中的'self.attributes'仍然获得值?

【问题讨论】:

    标签: python class constructor initialization


    【解决方案1】:

    将可变对象(如列表)传递给 python 中的函数或方法时,在函数或方法的所有调用中使用单个对象。这意味着每次调用该函数或方法(在本例中为您的 __init__ 方法)时,每次都会使用完全相同的列表,并保留之前所做的修改。

    如果您想将一个空列表作为默认值,您应该执行以下操作:

    class TxdTest(object):
        def __init__(self, name = '', atrributes = None):
            self.name = name
            if attributes is None
                 self.attributes = []
            else:
                 self.attributes = attributes
    

    有关其工作原理的详细说明,请参阅:“Least Astonishment” in Python: The Mutable Default Argument,如 bgporter 所述。

    【讨论】:

    • @Sonny 为了简洁而不失可读性,考虑使用三元运算符self.attributes = list() if attributes is None else attributes
    【解决方案2】:

    简答:只有一个列表,因为它是在函数定义时分配的,而不是在调用时分配的。所以类的所有实例都使用相同的attributes 列表。

    与类无关;每当您在函数参数列表中使用可变对象作为默认值时,就会出现问题。

    【讨论】:

      【解决方案3】:

      这是此处描述的“Python 陷阱”之一:http://zephyrfalcon.org/labs/python_pitfalls.html

      (您需要 #2 和 #5。这篇文章来自 2003 年,但它仍然适用于现代 Python 版本。)

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 2016-07-03
        • 2016-01-28
        • 2020-03-27
        • 1970-01-01
        • 1970-01-01
        • 2015-06-16
        • 2021-02-21
        • 2013-11-17
        相关资源
        最近更新 更多