1

this question is not a duplicate of the other overloading question because I am attempting to reference self.args in the function. The answer given in that question does not satisfy, since if I implement that answer, I will get an error. However, in other languages, this is easily done through method overloading...so this question is highly related to the other question.

So I have a method,

class learner():
      def train(a ton of arguments):
            self.argA = argA, 
            etc.

And I want to call train with just one value, and have it use all the self calls to populate the other arguments...but it is a circular reference that python doesn't seem to support. Ideally, I would write:

class learner():
    def train(self, position, data = self.data, alpha = self.alpha, beta = etc):
          ...do a bunch of stuff

    def roll_forward(self,position):
          self.alpha += 1
          self.beta += 1
          self.train(position)

How would I do this? In other languages, I could just define a second train function that accessed the internal variables...

currently, I have a janky hack where I do this:

class learner():
     def train(...):
             ....
     def train_as_is(self,position):
         self.train(position,self.alpha,self.beta, etc.)

But this is a pretty big class, and a ton of functions like that are turning my code into spaghetti...

3
  • Possible duplicate of How do I use method overloading in Python? Commented Dec 12, 2015 at 17:42
  • No, not a duplicate. I actually went to that question for my answer. Not sure you understand what I am trying to do. Commented Dec 12, 2015 at 17:43
  • Parameter defaults get evaluated at module load time. So even if you didn't have the problem of self reference then the code wouldn't do what you intended because the modification of self.alpha would not affect the default value of train(). Commented Dec 12, 2015 at 17:59

3 Answers 3

6

An enhancement on other answers is to use a defaults dictionary:

def train(self, position, **kwargs):
    defaults = {
        'a': self.a,
        'b': self.b,
         ...etc...
    }
    defaults.update(kwargs)
    ... do something with defaults

def roll_forward(self,position):
      self.alpha += 1
      self.beta += 1
      self.train(position)
Sign up to request clarification or add additional context in comments.

4 Comments

I like this one. Thanks dude.
this have the risk that you can call it with a extra keyword argument that is not expect...
true. going to think about it.
Wound up implementing an init_and_train() function that takes all the arguments optionally, with their default values set...and a train() function that takes the primary input and a dictionary...the dictionary is checked by the class for content to update the self values, so risk is mitigated. Thanks for pointing that out.
4

Not sure if I follow your question 100% but usual pattern is to use None as a default value:

class Foo(object):
    def __init__(self):
        self.a = ...
        self.b = ...
        ...

    def foo(self, position, a=None, b=None, ...):
        if a is None:
            a = self.a
        if b is None:
            b = self.b
        ...

You can simplify that by using or:

def foo(self, position, a=None, b=None, ...):
    a = a or self.a
    b = b or self.b
    ...

however that is not as reliable in case you will try to pass falsy values like 0 the or part will kick in

1 Comment

no, I didnt forget. It should be if a is None since you want to check when its None, you want to default a to whatever self.a is.
1

you can give those parameter a default value of None, then check if any of them is None and if it is, assign the desired value like this

class learner():
    def train(self, position, data = None, alpha = None, beta = None,etc...):
        if data is None:
            data = self.data
        if alpha is None:
            alpha = self.alpha
        ...etc
        ...do a bunch of stuff

1 Comment

This one looks good. would just make the initial call to train complex.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.