开发者

Python class methods

开发者 https://www.devze.com 2022-12-17 15:24 出处:网络
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

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?

0

精彩评论

暂无评论...
验证码 换一张
取 消