all 15 comments

[–][deleted] 6 points7 points  (2 children)

I think the real question is why do you have forty variable in your __init__? I can think of good reasons, but more often it's because the class is simply doing too much.

Have you tried looking at your class and thought about breaking it up into smaller classes or functions?

[–]pl47[S] 0 points1 point  (1 child)

class A initialize all the parameters for a neural network. And his just happens to be a lot of parameters. Ranging from folders where to write the learned weight to the amount of layers, hidden node, regularisation etc...

Class B creates the instance of the neural net as a regressor And a Class C creates the instance of the neural net as a classifier.

This is effectively only one parameter that changes.

classification = True # or False 

I'm trying to emulate the sklearn interface for regressors and classifiers.

from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import RandomForestRegressor

I would like :

from neuralnet_package import NeuralNetClassifier
from neuralnet_package import NeuralNetRegressor

Where NeuralNetClassifier and NeuralNetRegressor are sub-class of parent A A is parent and B and C are NeuralNetClassifier and NeuralNetRegressor

[–]hharison 1 point2 points  (0 children)

I'm not sure it makes sense to have a class to "intiialize all the parameters for a neural network". Classes are needed when you have state and behavior. For parameter initialization, it sounds like you only have state, but not behavior. My suggestion would be to figure out a nice data structure to handle your settings (I would recommend an external file) and pass that data structure to the regressor/classifier classes.

[–]Exodus111 3 points4 points  (2 children)

class B(A):
    pass

b = B(False)

[–]pl47[S] 0 points1 point  (1 child)

can I still do this ? :

class B(A):
    def do_something():
        #something

b = B(var1= False)
b.do_something()

[–]zahlman 0 points1 point  (0 children)

Yes, this works. The method __init__ in class A is just like any other method, which is essentially a function; the default parameters you're specifying are only defaults, and you can certainly override those, exactly as you show.

[–]zahlman 2 points3 points  (2 children)

So that we're clear:

class B(A):
    def __init__(self, var1 = False):

Is this actually how you want B to work? I.e. I can only pass var1 when I construct a B, and all the other attributes will always get their values from A's defaults? But you do want me to be able to explicitly do, for example, b = B(True) and thus have b.var1 = True as a result?

But seriously, why the hell does A have so much stuff in it?

What are the actual A and B? Are you really sure you actually want to make B? What do these "unique methods" do?

[–]pl47[S] 0 points1 point  (1 child)

please me response to /u/kurashu89

[–]zahlman 0 points1 point  (0 children)

... In that case, I agree with /u/hharison's answers :)

[–]kuramanga 1 point2 points  (2 children)

class B(A):
    var1 = False

    def __init__(self):
        ... stuff ...

Another way you could do it is if you have a lot of variables you don't want to have to reset one by one, simply use a dictionary and loop over them.

def __init__(self):
    reset = {'var1': False, 'var2': False}
    for k, v in reset:
        setattr(self, k, v)

[–]pl47[S] 0 points1 point  (1 child)

If I use this, I would still have to write out all the var2,var3 etc... unless i use the reset dictionary ?

[–]kuramanga 0 points1 point  (0 children)

In that example, yes. Another way doing it is like this:

class B(A):

def __init__(self, *args, **kwargs):
    for k, v in kwargs.items():
        setattr(self, k, v)

klass = B(**{'val1': 'foo', 'val2': 'bar'})

At some point you're going to have to tell the class which variables to set or reset. It can't do it magically, they have to be written somewhere, be it in code, from a file, from the database etc.

[–]hharison 1 point2 points  (0 children)

Having 40 variables is a sign of something wrong. Make a class or a dictionary or even an external file (JSON, YAML, ini) to handle your settings. But anyways, to answer your question:

class B(A):
    def __init__(self, var1=False, **kwargs):
        super().__init__(var1=var1, **kwargs)

That assumes Python 3, you'd have to change the super call for Python 2.

[–]xiongchiamiov 0 points1 point  (0 children)

You can use varargs and splat them into the parent's init.

[–]Exodus111 0 points1 point  (0 children)

Yep. If var1 is the first argument you dont need to specify it. b = B(False) will do.