-3

What's the difference between instantiate a class with () and without () ?

Here is the code I am working with:

import numpy as np

from sklearn.datasets.samples_generator import make_regression
from sklearn.model_selection import train_test_split

from sklearn.linear_model import LinearRegression

X, y = make_regression(n_samples=100, n_features=10, n_informative=2, 
                   noise=3.0, random_state=1)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)

Here comes my question. I need to instantiate the class LinearRegression and when I do it like it follows, everything works fine.

model = LinearRegression()
model.fit(X_train, y_train)

Instead if I do it in this other way:

model = LinearRegression
model.fit(X_train, y_train)

I get the following error:

TypeError: fit() missing 1 required positional argument: 'y'

So I guess the problem is the missing (). What's happening exactly when I omit the () ? Is it equivalent to what follows ?

from sklearn.linear_model import LinearRegression as model 
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Harry C.
  • 41
  • 1
  • 4
  • 5
    `LinearRegression` is the class. `LinearRegression()` makes a new instance of that class, i.e. it calls `__init__`. – AJF Jun 24 '18 at 12:19
  • The reason you get that error is that `LinearRegression.fit` looks for three parameters: `self, x, y`. So it assumes X_train is `self` and `y_train` is `x`. When you do `LinearRegression().fit()` you are calling the method on the instance so `self` is already passed and you get the expected result. – ayhan Jun 24 '18 at 12:36

2 Answers2

2

The difference is that LinearRegression is the class definition itself, whereas LinearRegression() creates an instance of that class.

# Let’s define an example class without any content.
>>> class Foo(object):
...     "Some class definition"
... 
# Assign the class without () simply assigns the class itself.
>>> foo = Foo
>>> type(foo)  # foo is a type Foo.
<class 'type'>
# Assign the class with () creates an instance (an object) of that class.
>>> foo = Foo()
>>> type(foo)  # foo is an instance of type Foo.
<class '__main__.Foo'>

There are plenty of articles around that explain the difference between a “class” and an “instance of a class” (or an “object of type class”), for example here.

Jens
  • 8,423
  • 9
  • 58
  • 78
1

While variable = Class() assigns a new instance of the type "Class" to the variable, variable = Class simply assigns the type "Class" to it.

Whenever you define an instance method, say foo(self) for a type, its name will be visible both on the type object as well as any of its instances. The difference is that at Class.foo() you have the "raw" function object, behaving exactly as a locally defined function would, whereas a call to Class().foo() will result in a "method object" being assembled behind the scenes from the raw function object on the type object and the instance object the method is called on, consuming the first parameter that is typically called "self".

Consequently the error missing 1 required positional argument:: The raw function object defined on the type object expects three positional arguments and interprets the parameter first passed as "self".

Sam
  • 811
  • 5
  • 9