I have a class as follows:
class X:
def __init__(self):
self.sum_x =0.0
self.sum_x_squared=0.0
self.var_x =0.0
self.sum_y =0.0
self.sum_y_squared=0.0
self.var_y =0.0
def update(self,data):
[x,y,vx,vy]=data
self.update_sums(self.sum_x,self.sum_x_squared,x)
self.update_sums(self.sum_y,self.sum_y_squared,y)
.
def update_sums(self,sums开发者_开发问答,squares,val):
sums += val
squares += val*val
.
I would like to pass the member variables sum_x
, sum_x_squared
etc to the update_sums
function for update how do I do this, I am confused.
Thanks
First, note that your question has nothing to do with classmethod (which makes class methods in Python) -- it's entirely about normal instance methods (you should edit your title... or your question, if you do mean it to be about class methods).
For the Q as it stands, the only way to do what you want is to pass the names of the attributes that the method needs to set (or enough data to let the method reconstruct the names), e.g.:
def update(self,data):
x, y, vx, vy = data
self.update_sums('x' , x)
self.update_sums('y' , y)
def update_sums(self, attname, val):
sums = 'sum_' + attname
setattr(self, sums, getattr(self, sums, 0) + val)
sums = 'sum_' + attname + '_squared'
setattr(self, sums, getattr(self, sums, 0) + val * val)
I would not recommend this approach, in general, as it makes code bulkier, less readable, and marginally less efficient than the elementary approach of just hard-coding the attribute names. If the auxiliary method (here update_sums
) encapsulates a lot of tricky logic that you're really very keen to avoid duplicating, maybe; but while eliminating repetition is a very worthwhile task, it takes taste and balance to avoid going overboard with it;-).
you don't need to pass nothing but the self
, which you're mandated to do anyway:
def update_sums(self, val):
self.sum += val
self.sum_squared += val * val
...
the call will be the following: self.update_sums(x)
The way you designed the class so far is not very useful or flexible, I'd suggest something along these lines:
class X:
def __init__(self):
self.sums = [0] * 4
self.sums_squared = [0] * 4
def update(self, data):
self.update_sums(data)
def update_sums(self, vals):
self.sums = [i + j for i, j in zip(self.sums, vals)]
self.sums_squared = [i + j*j for i, j in zip(self.sums, vals)]
It's still no ideal, because I don't know what the purpose of this whole thing is, but it's better then to have all those values.
No need. You have direct access to self.sumx, etc.
Are you sure that the functions do belong to the class X? You seem to be missing semicolon and whitespace formatting.
You don't have to pass them, update_sums can access them just like update can.
It looks to me like there is another class in there wanting to be let out. I would remove duplication by refactoring the code like this:
class SumOfSquares(object):
def __init__(self):
self.sum = 0.0
self.squares = 0.0
def update(self, val):
self.sum += val
self.squares += val * val
class X(object):
def __init__(self):
self.x = SumOfSquares()
self.y = SumOfSquares()
def update(self,data):
[x,y,vx,vy]=data
self.x.update(x)
self.y.update(y)
self.sumx, self.sum_x_squared?
精彩评论