Python类无意的单例

时间:2017-02-15 15:11:30

标签: python singleton

所以我得到了这段代码:

    # The Headers class is like a dictionary but is able to store multiple name-value pairs with the same name
class Headers:
    def __init__( self, index = [] ):
        self.index = index

    def __contains__( self, name ):
        for own_name, value in self.index:
            if name.lower() == own_name.lower():
                return True
        return False

    def __getitem__( self, name ):
        for i in range( len( self.index ) ):
            if name.lower() == self.index[i][0].lower():
                return self.index[i][1]

    def __iter__( self ):
        return HeadersIterator( self )

    def __setitem__( self, name, value ):
        for i in range( len( self.index ) ):
            if name.lower() == self.index[i][0].lower():
                self.index[i][1] = value

    def add( self, name, value ):
        self.index.append( (name, value) )

class HeadersIterator:
    def __init__( self, headers, index = 0 ):
        self.headers = headers
        self.index = index

    def __next__( self ):
        if self.index >= len( self.headers.index ):
            raise StopIteration()

        result = self.headers.index[ self.index ]
        self.index += 1

        return result

我只是遇到了这个问题,当我尝试使用它时,它似乎就好像它是一个单身人士。这是一些其他代码,显示我使用它:

def headers( self ):
        hs = Headers()
        print("huh?", Headers, hs.index, )

        # Most headers start with HTTP_
        for name, value in self.environ.items():
            if name.startswith( 'HTTP_' ):
                parts = [ (x[0].upper() + x[1:].lower()) for x in name[ len('HTTP_') : ].split( '_' ) ]

                hs.add( '-'.join( parts ), value )

        # Some don't
        if 'CONTENT_LENGTH' in self.environ:
            hs.add('Content-Length', str(self.environ['CONTENT_LENGTH']) )

        return hs

现在它似乎是第二次打印"呵呵?"看来,hs变量似乎指向同一个Headers对象,这意味着它只会继续添加到它返回的同一个Headers变量,下次有更多的条目。 非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

Header本身不是单身,但它们全部指向相同的index 。这是由于构造函数:

def __init__( self, index = []):
    # ...

这意味着Python构造一个列表,并且对于没有给定index的每个构造函数调用,都会给出对相同列表的引用。

您可以通过传递不可变(例如None)来解决它,然后使用if语句并构建一个新列表,如:

def __init__( self, index = None):
    if index is None:
        index = []
    # ...

尽管确实有一些方法可以将全局引用传递给构造函数(就像你在这里一样),但建议谨慎使用可变对象作为默认值:始终考虑传递不可变量(如42None'foobar'True(),...)。