__init__ 方法获取一个值,但没有传递任何值[重复]

2023-12-22

我有课TextBuffer。它有一个__init__函数可用于传递内容的初始值TextBuffer。如果没有传递任何值,则应使用空列表作为默认值。

该类有一个方法add,为了将文本添加到 TextBuffer:

a = TextBuffer()
a += "TEXT"

由于某种原因,调用__init__不带参数的方法不使用默认值[] for lst,但是之前添加到另一个实例的值TextBuffer,这不在__init__ call

a = TextBuffer()
a += "BUFFER A"
b = TextBuffer()  ### lst in the __init__ call has the value of ["BUFFER A"]
b += "BUFFER B"

我不知道为什么会发生这种情况。也许我做错了什么__add__ method?

请考虑完整的示例代码:

import pprint

### Two functions for byte/string conversion in Python3
def b(x):
    if ( type(x) == type(b'')):
        return x
    else:
        return x.encode(encoding='UTF-8')
def s(x):
    if ( type(x) == type(b'') ):
        return x.decode(encoding='UTF-8')
    else:
        return x


class TextBuffer():
    def __init__( self, lst = [], maxlines = None ):
        self.content = []
        if ( type(lst) == type([])):
            if (len(lst) > 0):
                print("INIT got a nonempty lst value:")
                pprint.pprint(lst)
                print("------------------------------")
            self.content = lst


    def __getitem__( self, i ):
        try:
            return self.content[i]
        except IndexError:
            return None

    def __iter__( self ):
        for line in self.content:
            yield line

    def __contains__( self, item ):
        return item in self.content

    def __len__( self ):
        return len(self.content)

    def __add__( self, item ):
        self.content.append(item)
        return self

    def __radd__( self, item ):
        return self.__add__(item)

    def __repr__( self ):
        result = ""
        for line in self.content:
            if ( type(line) == type(b"") ):
                result+=s(line)
            else:
                result+=line
        return result

    def __str__( self ):
        return repr(self)

    def __unicode__( self ):
        return repr(self.content)

### TextBuffer INIT with empty list creates an empty textbuffer
a = TextBuffer(lst=[])
print("a = TextBuffer(lst=[])")

a += "BUFFER A"


### TextBuffer INIT with empty list creates an empty textbuffer
b = TextBuffer(lst=[])
print("b = TextBuffer(lst=[])")

b += "BUFFER B"

print("Content of TextBuffer a:")
print(a)
print("Content of TextBuffer b:")
print(b)

print("-------------------------")

### TextBuffer INIT without any parameters should use default value for lst of []
### So an empty list. Should be the same as TextBuffer(lst=[])
a = TextBuffer()
print("a = TextBuffer()")

a += "BUFFER A"

### TextBuffer INIT without any parameters should use default value for lst of []
### So an empty list. Should be the same as TextBuffer(lst=[])
### But now, the value of lst is not [], it is the string added to TextBuffer 'a': ['BUFFER A']
b = TextBuffer()
print("b = TextBuffer()")

b += "BUFFER B"

print("Content of TextBuffer a:")
print(a)
print("Content of TextBuffer b:")
print(b)

你不能使用lst = [] 作为默认参数在这种情况下,因为 Python 将列出一份清单记忆中,每次都过去对同一对象(列表)的引用到构造函数。这意味着您的两个对象共享相同的lst因此,一个对象所做的修改会反映在另一个对象中,反之亦然。

您可以使用以下技巧:

def __init__( self, lst = None, maxlines = None ):
    if lst is None:
        lst = []
    #... (remainder of the constructor)

因为在这里你强制Python构建一个新列表。显然你可以使用另一个值None;但我认为对于你的情况来说这就足够了。

一般来说,这是一个好主意not feed mutable对象作为默认值,始终使用不可变对象。然而,正如 @hiroprotagonist 描述的那样,在某些情况下需要这种行为(例如记忆),但我建议对这些情况要非常小心。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__init__ 方法获取一个值,但没有传递任何值[重复] 的相关文章

随机推荐