2011-11-16 3 views
1

私はPythonクラス(link)についてこれを読んでいます。それは私が持っている問題であるようです。ここでPython 2.7でクラスとそのリストメンバーをコピーし、参照をコピーしないにはどうしたらいいですか?

は私のクラスや他のコードからの抜粋です:私はリストに何かをするBのメソッドを呼び出すとき

class s_board: 

    def __init__(self): 
     self.__board = [[n for n in range(1, 10)] for m in range(81)] 
     self.__solved = [False for m in range(81)] 

    def copy(self): 
     b = s_board() 
     b.__board = self.__board[:] 
     b.__solved = self.__solved[:] 
     return b 

if __name__ == '__main__': 
    A = s_board() 
    B = A.copy() 
    B.do_some_operation_on_lists() 

、Aのリストも同様に影響を受けているようです。

だから私の質問:

  • は私が正しく、クラスやリストをコピーすることではないのですか?
  • 別の問題はありますか?
  • クラスの新しいコピーが得られるように修正するにはどうすればよいですか?代わりにcopy()

    copy()deepcopy()を使用して

答えて

2

self.__board[:]はすべてへの参照を含む新しいリストを作成self.__boardにあったものと同じです。 self.__boardにはリストが含まれており、リストは変更可能であるため、部分的に別名付きのデータを持つ2つのs_boardインスタンスになり、一方を変更すると他方に影響します。

Raymond Hettingerが提案したように、copy.deepcopyを使用すると、オブジェクトの真のコピーを取ってデータを共有しないことが(主に)保証されます。 deepcopyが動作しないいくつかの奇妙なオブジェクトがあると信じていますが、リストや簡単なクラスのような普通のものでは正常に動作します。

他にも提案があります。 b = s_board()に電話すると、新しいブランクボード用のリストを作成するためのすべての作業に行き、b.__boardb.__solvedに割り当てることでそれらを破棄します。なくても、あなたはA = s_board()呼び出す場合

class s_board: 

    def __init__(self, board=None, solved=None): 
     if board is None: 
      self.__board = [[n for n in range(1, 10)] for m in range(81)] 
     else: 
      self.__board = copy.deepcopy(board) 
     if solved is None: 
      self.__solved = [False for m in range(81)] 
     else: 
      self.__solved = copy.deepcopy(solved) 

    def copy(self): 
     b = s_board(self.__board, self.__solved) 
     return b 

今、あなたは新しい空白のボードを取得し、あなたがA.copy()を呼び出す場合は、Aの個別のコピーを取得:次のような何かをする方が良いだろうようなもののようです新しいブランクボードを割り当てて廃棄しなければなりませんでした。

0

試みは、それができる場合は、deepcopy()は参照を使用せずに、メンバーのすべてをコピーする必要があります参照を挿入します。

+1

Mikeは 'copy'モジュールから' copy'を使用していません。彼は自分のクラスで自分の作成方法を使用しています。問題は、リストのリストのスライスコピーです。しかし、はい、「ディープコピー」が解決策です。 – Ben

+0

@Benああ私の間違い。 –

0

内部のリストは共有されています。ここで何が起こっているかを説明して記事です:http://www.python-course.eu/deep_copy.php

コードを修正するには、何も共有データがないことを確認するcopy.deepcopyを使用することができます。

def copy(self): 
    b = s_board() 
    b.__board = copy.deepcopy(self.__board) 
    b.__solved = copy.deepcopy(self.__solved) 
    return b 
関連する問題