Constructor gets called twice when dynamically instantiating class - python

I am using importlib & getattr to dynamically create an instance of a class. But, when i run Proxy.py that is provided below, the constructor gets called twice and i get duplicate results. Thanks in advance. (Python 3.6.1)
Result
inside Cproxy contructor
inside Cproxy read()
inside Cproxy contructor
inside Cproxy read()
Runner.py
import importlib
class Crunner:
def __init__(self, nameofmodule, nameofclass):
self.run(nameofmodule, nameofclass)
def run(self, nameofmodule, nameofclass):
module = importlib.import_module(nameofmodule)
class_ = getattr(module, nameofclass)
instance = class_()
instance.read()
Proxy.py
from Runner import Crunner
class Cproxy:
def __init__(self):
print("inside Cproxy contructor")
def read():
print("inside Cproxy read()")
Crunner("Proxy", "Cproxy")

Your proxy module is imported twice - once as __main__ (when you run python Proxy.py) and once as Proxy (when it's imported by Crunner).
The solution is simple: guard the call to Crunner() so it's only executed when Proxy is used as script:
if __name__ == "__main__":
Crunner("Proxy", "Cproxy")

Related

How to Import Class From Inside the Main function of another file?

I want to import a class defined within the main() function of another file to my current script.
Here is the code:
File A.py
def main():
class Aclass()
def foo(self):
return x
I want to include the above Aclass in my current file but when I import A.py I get the error:
no attribute 'Aclass"
Because you're declaring the class inside a function, so you will be able to import main() but not Aclass(). Just move your class definition outside the main function and that will do the trick
I don't know what do you want by that but You can return that class when you run that function.
For example:
def main():
class Aclass():
def __init__(self):
pass
return Aclass
f = main()
y = f()
Your class's object now is y variable
Your way in writing code is not correct but every one has thoughts or ideas that they want to do it.

How to run given Python script with class, init and main from cmd?

I'm supplid with script.py file with Python contents of which this is psuedo code:
import pandas as pd
import numpy as np
params = {...}
class SomeClass:
def __init__(self, ab):
self.ab = ab
self.de = None
def main(self):
self.foo()
#staticmethod
def DoSomethingUsefull(abc, params=params):
abc['x'] = abc['Red Fox'].copy()
return some_list(abc);
def foo(self):
self.de = SomeClass.DoSomethingUsefull(self.ab)
self.de['de'] = "de"
I cannot change the contents of the file, just use it as is. Eventually I need to execute the script from external (C#) code, currently trying to run from cmd (Python is installed). My question is how to execute from command line? If it's not possible to execute from command line and a wrapper script is needed, what will it look like?
Using WinPython 3.9.10
as #DeepSpace said, this file just contains a definition of a class, it won't do anything by itself.
You can create a python file that instantiates the class and calls some of it's methods
something like
import SomeClass
ab = {'Red Fox': 42}
myClass = SomeClass(ab) # instantiate the class
myClass.main() # call the main method.
Bear also in mind that you will need to modify the File at least to correct the typos like self.de - None otherwise you won't be able to import the class.
If you are going to modify the file anyway to create the typos (Yeah, I know you said you can't modify it, but you must), you could just make the file "executable" by putting the code outside the class like this:
if __name__ == "__main__":
ab = {'Red Fox': 42}
myClass = SomeClass(ab) # instantiate the class
myClass.main() # call the main method.
This way you don't need an extra file.

python: call a class from a script in a different directory and get function

I have a script that I am currently working on, named exp1.py and it's located in
/project/exp1.py
In this script, I am trying to call a function named computelikelihood(), which is inside the class Class(), which is in script method.py, in a different directory:
/project/methods/c_CLASS/method.py
So, in my code in exp1.py, I do this:
import sys
sys.path.append('/project/methods/c_CLASS/')
Which gets me to the folder where method.py is located, but when I want to call the Class() from the method.py, so that I get the function computelikelihood(), that I actually want, I get error. I try this:
from method import Class
from Class import computelikelihood
But I get ImportError: No module named Class. Can anyone help?
EDIT
This is how the __init__ of my Class looks like:
class Class:
def __init__(self,e2wl,w2el,label_set):
self.e2wl = e2wl
self.w2el = w2el
self.workers = self.w2el.keys()
self.examples = self.e2wl.keys()
self.label_set = label_set
Since you are trying to use a method from a Class, you should do so via the class. Do not import the function alone as it isn't intended to be used as such:
from method import Class
Class.computelikelihood()
However, this only works if computelikelihood is a static/class method:
class Class:
#classmethod
def computelikelihood(cls):
...
# or
#staticmethod
def computelikelihood():
...
If it's an instance method:
class Class:
def computelikelihood(self):
...
You'll need to first instantiate an object of class Class:
from method import Class
classObject = Class()
classObject.computelikelihood()

Parent class init is executing during inheritence

One basic question in OOP.
test.py file content:
class test(object):
def __init__(self):
print 'INIT of test class'
obj = test()
Then I opened another file.
I just inherited from the above test class:
from test import test
class test1(test):
def __init__(self):
pass
So when I run this second file, the __init__() from the parent class is executed (the INIT got printed).
I read that I can avoid it by using
if __name__ == '__main__':
# ...
I can overcome this, but my question is why the parent class's init is executing as I am just importing this class only in my second file. Why is the object creation code executed?
Importing a module executes all module-level statements, including obj=test().
To avoid this, make an instance only when run as the main program, not when imported:
class test(object):
def __init__(self):
print 'INIT of test class'
if __name__ == '__main__':
obj=test()
The problem is not the inheritance but the import. In your case you execute obj=test() when importing:
from test import test
When you import test, its name __name__ is test.
But when you run your program on the command line as main program with python test.py, its name is __main__. So, in the import case, you skip obj=test()if you use:
if __name__ == '__main__':
obj=test()

Python internal entity mocking

I'd like to test a method, whether it calls a specific method of a temporary internal object or not. (ConfigParser.read)
So the object is created inside, and it's not accessible from the outside after the method exits.
Using python 2.7
In foobar.py
import ConfigParser
class FooBar:
def method(self, filename):
config=ConfigParser.ConfigParser()
config.read(filename)
do_some_stuff()
I'd like to test whether config.read was called.
As I understand, the patch decorator was made for this, but unfortunately the MagicMock object the testcase receives is not the same that is created inside, and I can't get near the object that lives inside the method.
I tried like this:
class TestFooBar(TestCase):
def setUp(self):
self.myfoobar = FooBar()
#mock.patch('foobar.ConfigParser')
def test_read(self,mock_foobar):
self.myfoobar.method("configuration.ini")
assert mock_foobar.called # THIS IS OKAY
assert mock_foobar.read.called # THIS FAILS
mock_foobar.read.assert_called_with("configuration.ini") # FAILS TOO
The problem is:
- mock_foobar is created before the self.myfoobar.method creates the ConfigReader inside.
- when debugging mock_foobar has internal data about the previous calls, but no "read" property (the inner MagicMock for mocking the read method)
Of course one way out is refactoring and giving the .read() or the init() a ConfigReader object, but it's not always possible to change the code, and I'd like to grasp the internal objects of the method without touching the module under test.
You're so close! The issue is that you are mocking the class, but then your test checks that read() is called on that mock class - but you actually expect read() to be called on the instance that is returned when you call the class. The following works - I find the second test more readable than the first, but they both work:
import ConfigParser
from unittest import TestCase
from mock import create_autospec, patch, Mock
class FooBar(object):
def method(self, filename):
config=ConfigParser.ConfigParser()
config.read(filename)
class TestFooBar(TestCase):
def setUp(self):
self.myfoobar = FooBar()
#patch('ConfigParser.ConfigParser')
def test_method(self, config_parser_class_mock):
config_parser_mock = config_parser_class_mock.return_value
self.myfoobar.method("configuration.ini")
config_parser_class_mock.assert_called_once_with()
config_parser_mock.read.assert_called_once_with("configuration.ini")
def test_method_better(self):
config_parser_mock = create_autospec(ConfigParser.ConfigParser, instance=True)
config_parser_class_mock = Mock(return_value=config_parser_mock)
with patch('ConfigParser.ConfigParser', config_parser_class_mock):
self.myfoobar.method("configuration.ini")
config_parser_class_mock.assert_called_once_with()
config_parser_mock.read.assert_called_once_with("configuration.ini")

Categories