Python:创建 class 实例的副本
Python: Create a duplicate of an instance of a class
我有一个我定义的 class BipartiteGraph 的实例 'graph_main'。我现在需要的是保持此实例不变,但创建此 class 的另一个实例 'graph1',它与 'graph_main' 相同。但出于某种原因, graph_main 也在我根本不使用它的时候不断变化。我是 Python 的新手,刚来几周。因此,如果有相关文档可以指导我了解 Python 中对象的范围,我将不胜感激。
MWE:
import numpy
import testBipartiteUtils
import random
#These are Bipartite graph parameters
N=30 #No of Bit Nodes
K=10 #No of Check Nodes
rdeg=2
graph_main = testBipartiteUtils.BipartGraph([])
for NodeIndex in range(0, K):
graph_main.addBitNode(NodeIndex)#Adding Bit Node. No edges added
for NodeIndex in range(0, N):
graph_main.addChkNode(NodeIndex)#Adding Check Node. No edges added
attachments=random.sample(range(0,K),rdeg)
for j in attachments:
graph_main.addEdge([j,NodeIndex])
for z in range(0,10):
chan=[]
for i in range(0,N):
chan.append(0)
graph1=graph_main **#creating a new object identical to graph_main?**
PeelGraph=testBipartiteUtils.Peeling(graph1,chan)
PeelGraph.zeroStep()
print "graph_main Nodes are-",len(graph_main.BitNodes),len(graph_main.ChkNodes)
print "graph1 Nodes are-",len(graph1.BitNodes),len(graph1.ChkNodes)
del PeelGraph
print "z=",z
我正在提供我的 Utils 文件,以防有人想 运行 它并查看,但我非常怀疑是否有必要这样做。所以我期望每个模拟在 graph_main 中输出恒定数量的位和检查节点(它是一个二分图 class),因为我没有改变它。这里我假设 graph1=graph_main 创建一个与现有 graph_main 相同的新对象。这是正确的,我的错误在别处吗?
testBipartiteUtils.py
import numpy
class Edge:
def __init__(self, n1, n2):
"""Constructor. Takes bit and check node IDs as arguments"""
self.node1=n1
self.node2=n2
def getNodes(self):
"""Returns a list containing the bit and check nodes for this edge"""
return [self.node1, self.node2]
def hasNodes(self, n1, n2):
"""Takes two node IDs. Returns true if the IDs match the two nodes of this edge in that order."""
if(self.node1==n1 and self.node2==n2):
return True
return False
class BitNode:
""" Basic node class."""
def __init__(self, name):
"""Constructor. Takes a node ID"""
self.ID=name
self.neighbors=[]
self.degree= 0
def addNeighbors(self, nbs):
"""Adds a list of neighbors to the current list. Takes a list of node IDs"""
for i in range(0, len(nbs)):
if(not nbs[i] in self.neighbors):
self.neighbors.append(nbs[i])
self.degree+=1
def getID(self):
"""Returns node ID"""
return self.ID
def getNeighbors(self):
"""Returns list of neighbor IDs"""
return self.neighbors
class ChkNode:
def __init__(self, name):
"""Constructor. Takes a node ID"""
self.ID=name
self.neighbors=[]
self.chan = int(-1)
self.degree= 0
def addNeighbors(self, nbs):
"""Adds a list of neighbors to the current list. Takes a list of node IDs"""
for i in range(0, len(nbs)):
if(not nbs[i] in self.neighbors):
self.neighbors.append(nbs[i])
self.degree+=1
def getID(self):
"""Returns node ID"""
return self.ID
def getNeighbors(self):
"""Returns list of neighbor IDs"""
return self.neighbors
class BipartGraph:
def __init__(self, eds):
"""Constructor. Takes a list of edge primitives, which is a list of two node IDs.
Iterates through the edges, creates nodes for unique node IDs, and adds all edges and nodes.
"""
self.size = 0
self.BitNodes = []
self.ChkNodes = []
self.edges = []
for i in range(0, len(eds)):
self.addEdge(eds[i])
def containsEdge(self, edgep):
"""Checks for an edge in the graph. Takes an edge primitive, which is a list of two node IDs. First ID is bit node, second ID is of Check node"""
for e in self.edges:
if(e.hasNodes(edgep[0], edgep[1])):
return True
def getBitNode(self, name):
"""Checks if a given Bit Node ID exists in the graph. If not, it creates and adds a Bit Node for the given ID. Returns the Bit Node"""
for i in range(0, len(self.BitNodes)):
if(self.BitNodes[i].getID()==name):
return self.BitNodes[i]
newNode = BitNode(name)
self.BitNodes.append(newNode)
return self.BitNodes[len(self.BitNodes)-1]
def getChkNode(self, name):
"""Checks if a given Chk Node ID exists in the graph. If not, it creates and adds a Chk Node for the given ID. Returns the Chk Node"""
for i in range(0, len(self.ChkNodes)):
if(self.ChkNodes[i].getID()==name):
return self.ChkNodes[i]
newNode = ChkNode(name)
self.ChkNodes.append(newNode)
return self.ChkNodes[len(self.ChkNodes)-1]
def getEdges(self):
"""Returns list of edges"""
return self.edges
def addBitNode(self, name):
"""Adds a Bit node, based on Bit node ID"""
newNode = BitNode(name)
self.BitNodes.append(newNode)
def addChkNode(self, name):
"""Adds a Check node, based on node ID"""
newNode = ChkNode(name)
self.ChkNodes.append(newNode)
def addEdge(self, edgep):
"""Adds an edge into the graph, and updates neighbors & degrees of relevant nodes.
Takes an edge primitive, a list of two node IDs
"""
if(not self.containsEdge(edgep)):
no1 = self.getBitNode(edgep[0])
no2 = self.getChkNode(edgep[1])
newEdge = Edge(edgep[0], edgep[1])
self.edges.append(newEdge)
no1.addNeighbors([no2.getID()])
no2.addNeighbors([no1.getID()])
class Peeling:
"""peeling decoder on a Bipartite graph class.
"""
def __init__(self, G,chan):
"""Constructor. Takes a graph and channel output vector as arguments"""
self.graph=G
for i in range(0,len(self.graph.ChkNodes)):
self.graph.ChkNodes[i].chan=chan[i]
self.deg1Chks=[]
def zeroStep(self):
self.graph.BitNodes.pop(0)
def peelIter(self):
self.graph.ChkNodes.pop(0)
使用 deepcopy
函数创建一个带有新指针的相同实例(与浅拷贝相反,浅拷贝是指向同一对象的另一个变量)。
import copy
graph1= copy.deepcopy(graph_main)
我不确定,但你不能这样做吗?...
x = ClassName(arguments, arguments...)
dup_of_x = x
因此,x 存储 x,dup_of_x 也存储 x
我有一个我定义的 class BipartiteGraph 的实例 'graph_main'。我现在需要的是保持此实例不变,但创建此 class 的另一个实例 'graph1',它与 'graph_main' 相同。但出于某种原因, graph_main 也在我根本不使用它的时候不断变化。我是 Python 的新手,刚来几周。因此,如果有相关文档可以指导我了解 Python 中对象的范围,我将不胜感激。
MWE:
import numpy
import testBipartiteUtils
import random
#These are Bipartite graph parameters
N=30 #No of Bit Nodes
K=10 #No of Check Nodes
rdeg=2
graph_main = testBipartiteUtils.BipartGraph([])
for NodeIndex in range(0, K):
graph_main.addBitNode(NodeIndex)#Adding Bit Node. No edges added
for NodeIndex in range(0, N):
graph_main.addChkNode(NodeIndex)#Adding Check Node. No edges added
attachments=random.sample(range(0,K),rdeg)
for j in attachments:
graph_main.addEdge([j,NodeIndex])
for z in range(0,10):
chan=[]
for i in range(0,N):
chan.append(0)
graph1=graph_main **#creating a new object identical to graph_main?**
PeelGraph=testBipartiteUtils.Peeling(graph1,chan)
PeelGraph.zeroStep()
print "graph_main Nodes are-",len(graph_main.BitNodes),len(graph_main.ChkNodes)
print "graph1 Nodes are-",len(graph1.BitNodes),len(graph1.ChkNodes)
del PeelGraph
print "z=",z
我正在提供我的 Utils 文件,以防有人想 运行 它并查看,但我非常怀疑是否有必要这样做。所以我期望每个模拟在 graph_main 中输出恒定数量的位和检查节点(它是一个二分图 class),因为我没有改变它。这里我假设 graph1=graph_main 创建一个与现有 graph_main 相同的新对象。这是正确的,我的错误在别处吗?
testBipartiteUtils.py
import numpy
class Edge:
def __init__(self, n1, n2):
"""Constructor. Takes bit and check node IDs as arguments"""
self.node1=n1
self.node2=n2
def getNodes(self):
"""Returns a list containing the bit and check nodes for this edge"""
return [self.node1, self.node2]
def hasNodes(self, n1, n2):
"""Takes two node IDs. Returns true if the IDs match the two nodes of this edge in that order."""
if(self.node1==n1 and self.node2==n2):
return True
return False
class BitNode:
""" Basic node class."""
def __init__(self, name):
"""Constructor. Takes a node ID"""
self.ID=name
self.neighbors=[]
self.degree= 0
def addNeighbors(self, nbs):
"""Adds a list of neighbors to the current list. Takes a list of node IDs"""
for i in range(0, len(nbs)):
if(not nbs[i] in self.neighbors):
self.neighbors.append(nbs[i])
self.degree+=1
def getID(self):
"""Returns node ID"""
return self.ID
def getNeighbors(self):
"""Returns list of neighbor IDs"""
return self.neighbors
class ChkNode:
def __init__(self, name):
"""Constructor. Takes a node ID"""
self.ID=name
self.neighbors=[]
self.chan = int(-1)
self.degree= 0
def addNeighbors(self, nbs):
"""Adds a list of neighbors to the current list. Takes a list of node IDs"""
for i in range(0, len(nbs)):
if(not nbs[i] in self.neighbors):
self.neighbors.append(nbs[i])
self.degree+=1
def getID(self):
"""Returns node ID"""
return self.ID
def getNeighbors(self):
"""Returns list of neighbor IDs"""
return self.neighbors
class BipartGraph:
def __init__(self, eds):
"""Constructor. Takes a list of edge primitives, which is a list of two node IDs.
Iterates through the edges, creates nodes for unique node IDs, and adds all edges and nodes.
"""
self.size = 0
self.BitNodes = []
self.ChkNodes = []
self.edges = []
for i in range(0, len(eds)):
self.addEdge(eds[i])
def containsEdge(self, edgep):
"""Checks for an edge in the graph. Takes an edge primitive, which is a list of two node IDs. First ID is bit node, second ID is of Check node"""
for e in self.edges:
if(e.hasNodes(edgep[0], edgep[1])):
return True
def getBitNode(self, name):
"""Checks if a given Bit Node ID exists in the graph. If not, it creates and adds a Bit Node for the given ID. Returns the Bit Node"""
for i in range(0, len(self.BitNodes)):
if(self.BitNodes[i].getID()==name):
return self.BitNodes[i]
newNode = BitNode(name)
self.BitNodes.append(newNode)
return self.BitNodes[len(self.BitNodes)-1]
def getChkNode(self, name):
"""Checks if a given Chk Node ID exists in the graph. If not, it creates and adds a Chk Node for the given ID. Returns the Chk Node"""
for i in range(0, len(self.ChkNodes)):
if(self.ChkNodes[i].getID()==name):
return self.ChkNodes[i]
newNode = ChkNode(name)
self.ChkNodes.append(newNode)
return self.ChkNodes[len(self.ChkNodes)-1]
def getEdges(self):
"""Returns list of edges"""
return self.edges
def addBitNode(self, name):
"""Adds a Bit node, based on Bit node ID"""
newNode = BitNode(name)
self.BitNodes.append(newNode)
def addChkNode(self, name):
"""Adds a Check node, based on node ID"""
newNode = ChkNode(name)
self.ChkNodes.append(newNode)
def addEdge(self, edgep):
"""Adds an edge into the graph, and updates neighbors & degrees of relevant nodes.
Takes an edge primitive, a list of two node IDs
"""
if(not self.containsEdge(edgep)):
no1 = self.getBitNode(edgep[0])
no2 = self.getChkNode(edgep[1])
newEdge = Edge(edgep[0], edgep[1])
self.edges.append(newEdge)
no1.addNeighbors([no2.getID()])
no2.addNeighbors([no1.getID()])
class Peeling:
"""peeling decoder on a Bipartite graph class.
"""
def __init__(self, G,chan):
"""Constructor. Takes a graph and channel output vector as arguments"""
self.graph=G
for i in range(0,len(self.graph.ChkNodes)):
self.graph.ChkNodes[i].chan=chan[i]
self.deg1Chks=[]
def zeroStep(self):
self.graph.BitNodes.pop(0)
def peelIter(self):
self.graph.ChkNodes.pop(0)
使用 deepcopy
函数创建一个带有新指针的相同实例(与浅拷贝相反,浅拷贝是指向同一对象的另一个变量)。
import copy
graph1= copy.deepcopy(graph_main)
我不确定,但你不能这样做吗?...
x = ClassName(arguments, arguments...)
dup_of_x = x
因此,x 存储 x,dup_of_x 也存储 x