Calling class methods in another python program - Unbound error issue - python

I have a program1.py that has the following structure:
program1.py
class program1_class()
def __init(self,var1):
command1
def method2(self,var1):
Then I have a program2 that imports the the class and needs to access the method2
program2.py
from program1_class import program1_class()
def method2(var1):
call_method2 = program1_class.method2(var1)
When I do this, I get the error
TypeError: unbound method predict_prob() must be called with LogisticRegressionSGD instance as first argument (got list instance instead)

There are a couple problems here-
from program1_class import program1_class() is invalid syntax in several ways.
The correct import statement is
from program1 import program1_class
Second, you tried to call a bound instance method on a class.
call_method2 = program1_class.method2(var1)
If you look at program1 you'll see that method2 is defined on the instance. You can tell this because the first argument is self. You call this by intantiating an instance of the class and then calling the method.
call_method2 = program1_class().method2(var1)

Related

Is it reasonable to let __init__ member must take self parameter?

I find when __init__ method lacks self parameter, only if there is no instantiation of this class, the compiler won't complain:
$ cat test.py
#!/usr/bin/python
class A():
def __init__():
print("A()")
$ ./test.py
But if there is a instantiation, the running time error will occur:
$ cat test.py
#!/usr/bin/python
class A():
def __init__():
print("A()")
A()
$ ./test.py
Traceback (most recent call last):
File "./test.py", line 6, in <module>
A()
TypeError: __init__() takes 0 positional arguments but 1 was given
Per my understanding, __init__() seems no use because it can't make any instance. So why doesn't the Python compiler enforce limitation such as when no self parameter in __init__ function, it will show error message? Is it reasonable? Or I miss something.
__init__ is not a special name at compilation time.
It is possible to do things with the symbol A.__init__ other than invoke it by trying to construct an A, and I think it is possible to replace the unusable __init__ function with a different function at runtime prior to trying to construct an A.
The check for a correct number of arguments is made when __init__ is called, as it is for any other method.
it must be one argument at least, we call it "self" usually, so your Python code maybe have a small change
#!/usr/bin/python
class A(object):
def __init__(self):
print("A()")
A()
__init__ is the initialization of an already created instance of a class, therefore it needs self, just like every other class method. If you want to handle the creation of the class, that is the __new__ method. This seems like a good description.
Don't let the fact that python doesn't complain unless the method is called confuse you.

Unit test failing after moving functions into a class

I'm trying to write a unit test for a function within a class but I'm having a little trouble. Before moving the importer function into a class, this test worked. However, now I get TypeError: grab_column_locations missing 1 required positional argument: 'sheet'. The importer function itself is correctly getting parsing sheet and works correctly when the program is run, but not when tested.
The line the TypeError refers to in the importer function is:
columns = self.grab_column_locations(sheet)
The test that's failing is:
from unittest import TestCase
from gtt import GTT
class TestGTT(TestCase):
def test_importer(self):
"""
Test import of valid xlsx file
:return:
"""
file_list = ['testData_1.xls']
# Run Test 1
importer_results = GTT.importer(GTT, file_list)
assert importer_results[0] == True
So essentially, when run from a test, importerisn't passing sheetto grab_column_locations. This only started happening when I moved both of those functions into a class. I know I broke something somehow, but what?
The error message says this:
TypeError: grab_column_locations missing 1 required positional argument: 'sheet'
This sounds like the function signature is:
def grab_column_locations(self, sheet):
Are you not calling it from an instance of the class owning this function?
That is, if the function belongs to the class Foo:
class Foo:
def grab_column_locations(self, sheet):
...
The error message makes me think that you're calling the function as follows:
Foo.grab_column_locations(sheet)
When you really should call it:
foo = Foo()
foo.grab_column_locations(sheet)
Alternatively, that function could be defined as a class method, if you don't want to bind it to an instance:
class Foo:
#classmethod
def grab_column_locations(self, sheet):
...
Then you can call it as follows:
Foo.grab_column_locations(sheet)
But anyway, this is just guesswork, since you didn't give much details.

Calling a test method in another TestClass

Hi I have the following test classes
logintests.py:
class SignOnTests(BaseTest):
def test_login_info(self):
#some code
passwordtests.py:
class ResetPasswordTests(unittest.TestCase):
def test_mytest(self):
#somecode
#Should Call SignOnTests.test_login_info()
I've tried putting on passwordtests.py:
from logintests import SignOnTests
But keep gettingTypeError: unbound method test_login_info() must be called with SignOnTests instance as first argument (got nothing instead)
Is it possible to call a test method within another module?

How does Python know the instance variable without defining __init__?

Let us consider the following example:
class X:
def run(self):
print("An example.")
X().run()
The output is:
> An example.
But when we omit the reference to the instance:
class X:
def run():
print("An example.")
X().run()
The output is:
TypeError: run() takes 0 positional arguments but 1 was given
When we instantiate the class, __ new __ gets called and the instance is created, ok. But how it requires an instance without defining __ init __? (I'm surprised because, I've always written __ init __ thinking that it was responsible for defining the convention / self name for referencing the variable). I'm confused.
When you call instance.run() if implicitly calls run(instance) which is why you're receiving the error:
TypeError: run() takes 0 positional arguments but 1 was given
That's also the reason why instance methods should have self as the first argument.
Second, you're using the old way of declaring a class - class X:
The new way1 is class X(object): but regardless if you're using the new/old annotation, the call X() will return an instance of the class, even in case you didn't define __init__.
And third, if you want to make it a class method you can either do what Pynchia suggested in the comment above (annotate the method with #staticmethod) or declare the method as a class method by specifying that the first argument is cls and annotating it as a class-method:
class X:
#classmethod
def run(cls):
print "a"
X.run() # prints a
1. According to Mark's comment below, in Python 3 we return to the "old way" of declaring a class. Good to know - thanks Mark!

Error - __init__() takes exactly 2 arguments (1 given)

I'm trying to initialize the class (extraropt) from another .py but it gives me an error, I've searched but I haven't found a solution.
Heres the code of the one py I'm calling from:
main.py:
class GameWindow(ui.ScriptWindow):
def __init__(self, stream):
import extraop
exec 'extraop.extraropt().Show(stream)'
And here's the code of the one py I'm trying to call(init and del only):
extraop.py
class extraropt(ui.Window):
def __init__(self, stream):
ui.Window.__init__(self)
self.BuildWindow()
self.stream=stream
def __del__(self):
ui.Window.__del__(self)
It gives this error:
Error - __init__() takes exactly 2 arguments (1 given)
In the line
exec 'extraop.extraropt().Show(stream)'
You are implicitly calling extraropt.__init__() by creating a new instance of extraopt. In your code, you show that extraropt.__init__() takes a second (stream) argument, so you have to pass that in.
extraop.extraropt(stream).Show()
Incidentally, there is no reason why you should be doing an exec rather than explicitly calling it as I did above. There is also no reason for you to have a __del__() method defined as you only call the parent __del__() method anyway.
You need to initialize the parent this way:
super(extraropt, self).__init__(stream)
The stream variable in the line exec 'extraop.extraropt().Show(stream)' should be passed into the constructor of the extraropt class, like this:
exec 'extraop.extraropt(stream).Show()'

Categories

Resources