Reputation: 13
Here I just copy my python code from my project:
from numpy.core.function_base import linspace
import numpy as np
from operator import mod
class contactPair:
itr = 0
rawData=[]
rawDataLabel=[]
uidi=0
uidj=0
Nc=0
cLoc=[0,0,0]
deltan=0
deltatAcc=0
Np=0
Fi=[0,0,0]
Fni=[0,0,0]
Fti=[0,0,0]
n=[0,0,0]
t=[0,0,0]
RVCP=[0,0,0]
def __init__(self,itr,label,cntinfo):
self.itr=itr
self.rawData=cntinfo
self.rawDataLabel=label
self.uidi=cntinfo[0]
self.uidj=cntinfo[1]
self.Nc=cntinfo[2]
self.deltan=cntinfo[6]
self.deltatAcc=cntinfo[7]
self.Np=cntinfo[8]
for k in range(3):
self.cLoc[k]=cntinfo[3+k]
self.Fi[k]=cntinfo[9+k]
self.Fni[k]=cntinfo[12+k]
self.Fti[k]=cntinfo[15+k]
self.n[k]=cntinfo[18+k]
self.t[k]=cntinfo[21+k]
self.RVCP[k]=cntinfo[24+k]
g=1
class par:
name = 0
itr = 0
uid = 0
rawData = []
rawDataLabel = []
mass = 0
pos = [0,0,0]
vel = [0,0,0]
acc = [0,0,0]
acc2 = [0,0,0]
hf =[0,0,0]
theta=[0,0,0]
omega=[0,0,0]
alpha=[0,0,0]
alpha2=[0,0,0]
dia=[0,0,0]
Nc=0
ppf=[0,0,0]
rotMat=[]
vol=0
density=0
mofi=[]
normalUnit=[]
angleToShearingPlane=0
def __init__(self,itr,label,parinfo):
#self.name=0
self.itr=itr
self.rawData=parinfo
self.rawDataLabel=label
self.name=parinfo[0]
self.mass=parinfo[2]
for k in range(3):
self.pos[k]= parinfo[3+k]
self.vel[k]= parinfo[6+k]
self.acc[k]= parinfo[9+k]
self.acc2[k]= parinfo[12+k]
self.hf[k]= parinfo[15+k]
self.theta[k]=parinfo[18+k]
self.omega[k]=parinfo[21+k]
self.alpha[k]=parinfo[24+k]
self.alpha2[k]=parinfo[27+k]
self.dia[k]= parinfo[33+k]
self.ppf[k]= parinfo[39+k]
self.uid = parinfo[36]
self.Nc = parinfo[37]
#ipDir1,ipDir2,ipDir3,mat=rotate(self.theta[0],self.theta[1],self.theta[2],1,0,0)
#self.rotMat=mat
#self.normalUnit=[ipDir1,ipDir2,ipDir3]
self.angleToShearingPlane=mod(self.theta[2]+2*np.pi,np.pi)
#self.angleToShearingPlane=mod(self.theta[1]+2*np.pi,np.pi)
t1=linspace(1,100,100)
c1=contactPair(1,[],t1)
p1=par(1,[],t1)
print(f"c1.cLoc: {c1.cLoc}")
print(f"p1.acc: {p1.acc}")
t2=linspace(101,200,100)
c2=contactPair(2,[],t2)
p2=par(1,[],t2)
print(f"c2.cLoc: {c2.cLoc}")
print(f"p2.acc: {p2.acc}")
print(f"c1.cLoc: {c1.cLoc}")
print(f"p1.acc: {p1.acc}")
and what I got from the python console is
c1.cLoc: [4.0, 5.0, 6.0]
p1.acc: [10.0, 11.0, 12.0]
c2.cLoc: [104.0, 105.0, 106.0]
p2.acc: [110.0, 111.0, 112.0]
c1.cLoc: [104.0, 105.0, 106.0]
p1.acc: [110.0, 111.0, 112.0]
What I did is
I don't know why the values of c1 and p1 are changed after creating c2 and p2.
Upvotes: 1
Views: 1414
Reputation: 1375
It's because you define everything as class variables instead of instance variables.
Focusing on cLoc inside of contactPair for example - you define it is a class variable that belongs to the entire class contactPair instead of belonging to an instance. This means that every instance of this class actually shares the same cLoc value. You don't want this to be the case, so you should instead have each instance create it's own version of the cLoc variable inside the __init__ constructor and assign it as an attribute of self.
Let me do a simple example illustrating this.
>>> class A():
... class_var = []
... def __init__(self):
... self.instance_var = []
... def append_more(self,x):
... self.class_var.append(x)
... self.instance_var.append(x)
...
>>> a = A()
>>> b = A()
>>> a.append_more(1)
>>> b.append_more(2)
>>> a.instance_var
[1]
>>> b.instance_var
[2]
>>> a.class_var
[1, 2]
>>> b.class_var
[1, 2]
>>> A.class_var
[1, 2]
>>> A.instance_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'instance_var' >>>
The class_var variable actually belongs to the class A, not to instances a or b. Executing a.class_var.append(x) basically results in python doing the following:
This basically means the expressions a.class_var or b.class_var refer to the same object as A.class_var.
But there was no instance_var variable created in the class context for A. That gets created in the __init__ constructor for specific instances and gets assigned to the instance not the class. This means that each instance has a unique list bound to instance_var in their object namespace.
Referring to a.instance_var causes python to find something at the instance level and not go and check the class level.
Note that if you were to overwrite class_var for a specific instance, you would basically cause the instance to point to some other object besides the class variable. This would not affect the original class variable or any other instance that did not do a similar "overwrite". For example, continuing the code above:
>>> a.class_var = [] # this makes a class_var reference to a new unrelated list at the instance level in a
>>> a.class_var
[]
>>> b.class_var
[1, 2]
>>> A.class_var
[1, 2]
>>> a.append_more(3) # will use new fresh unrelated list
>>> b.append_more(4) # will use original list belonging to class
>>> a.class_var
[3]
>>> b.class_var
[1, 2, 4]
>>> A.class_var
[1, 2, 4]
>>>
Upvotes: 1