How can I move a nested class to a separate file - python

In my Python class I have a nested class defined and it works well, but when I try to move the nested class to a separate file I'm having trouble importing it.
I've tried to follow a few tutorials on Mixins and importing but I keep running into the issue of my object not having the attribute of the new method.
class SomeClass():
def __init__(self):
pass
# # This works
# class NestedClass():
# def helloWorld():
# print("Hello World")
# But when I move it to a separate file (nestedclass.py) I'm having trouble importing
from nestedclass import NestedClass
c = SomeClass()
c.NestedClass.helloWorld() # throws an error when I try to import
The error message I receive is "Attribute Error: 'NestedClass' object has no attribute 'helloWorld'

Related

Attempt to patch a member function yields error AttributeError: 'module' object has no attribute 'object'

I would like to assert from a UT, TestRunner.test_run that some deeply nested function Prompt.run_cmd is called with the string argument "unique cmd". My setup besically resembles the following:
# Module application/engine/prompt.py
class Prompt:
def run_cmd(self, input):
pass
# Module: application/scheduler/runner.py
class Runner:
def __init__(self):
self.prompt = application.engine.prompt.Prompt()
def run(self):
self.prompt.run_cmd("unique cmd")
# Module tests/application/scheduler/runner_test.py
class TestRunner(unittest.TestCase):
...
def test_run(self):
# calls Runner.run
# Objective assert that Prompt.run is called with the argument "unique cmd"
# Current attempt below:
with mock.patch(application.engine.prompt, "run_cmd") as mock_run_cmd:
pass
Unfortunately my attempts to mock the Prompt.run_cmd fail with the error message
AttributeError: 'module' object has no attribute 'object'
If you wanted to patch a concrete instance, you could easily do this using mock.patch.object and wraps (see for example this question.
If you want to patch your function for all instances instead, you indeed have to use mock.patch. In this case you could only mock the class itself, as mocking the method would not work (because it is used on instances, not classes), so you cannot use wraps here (at least I don't know a way to do this).
What you could do instead is derive your own class from Prompt and overwrite the method to collect the calls yourself. You could then patch Prompt by your own implementation. Here is a simple example:
class MyPrompt(Prompt):
calls = []
def run_cmd(self, input):
super().run_cmd(input)
# we just add a string in the call list - this could be more sophisticated
self.__class__.calls.append(input)
class TestRunner(unittest.TestCase):
def test_run(self):
with mock.patch("application.engine.prompt.Prompt", MyPrompt) as mock_prompt:
runner = Runner()
runner.run()
self.assertEqual(["unique cmd"], mock_prompt.calls)

passing another class's fixture that returns array objects, got 'method' object is not subscriptable

need your insight:
In my own test setup (init_setup), I need to call another test that is already defined in class Test_Create_Tmp(). The issue is, this class has a fixture (init_api) that returns an array of function apis.
In init_setup: at line inv.test_post_inv_data(), i got 'method' object is not subscriptable, because inside it calls object's api by this: init_api["nAPI"].postJsonData(...)
How do I get this working, if I'm not allowed removing the fixture init_api() from that class?
I know I can get it working, by complete get rid fixture init_api, move its code just inside test_post_inv_data().
Thanks!
My own setup:
#pytest.fixture(scope="class")
def init_setup(self, read_data):
#import Test_Create_Tmp class here
inv = Test_Create_Tmp()
inv.test_post_inv_data(read_data, inv.init_api)
# this class is defined in another file
class Test_Create_Tmp():
#pytest.fixture
def init_api(self, client):
self.nAPI = NAPI(client) #NAPI is a class
self.sAPI = SApi(client) #SApi is another class
return {"nAPI": self.nAPI, "sAPI": self.sAPI}
def test_post_inv_data(self, read_data, init_api):
...
init_api["nAPI"].postJsonData(json.dumps(data))
I figured out myself. Just need to create the needed objects (ie, nAPI, sAPI) to invoke the call:
inv = Test_Create_Tmp()
init_api = {
'nAPI': NAPI(client), #create object of NAPI
'sAPI': SApi(client) #create object of SApi
}
inv.test_post_inv_data(read_data, init_api)

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()

Python: AttributeError: object has no attribute 'method'

I'm very much new to Python, essentially being pushed into a new project with no knowledge of the language whatsoever. I've gone over a number of tutorials to get a gist of the syntax and some of the functions, but I'm currently stumped on something that seems pretty basic.
I have a class GeoLocationHandlerObj in GeoLocationSolver.py which has a method 'myMethod':
class GeoLocationHandlerObj(object):
def __init__(self, connector, debug=0):
self._debug = debug
self.locator = GeoLocationSolverObj(connector)
return(None)
def close(self):
...
return(None)
def getAdr(self, point, lang):
...
return(None)
def getCom(self, point, lang):
...
return(None)
def getHmp(self, point, lang):
...
return(None)
def myMethod(self):
print "test"
return(None)
I import it and try to call myFunction:
import sys
import os
import psycopg2
import string
import json
import socket
import random
from GeoPackage.GeoCoding.GeoLocationSolver import *
if __name__ == "__main__":
connector = GeoPSConnectorObj(...)
handler = GeoLocationHandlerObj(connector)
handler.myMethod()
When I run this code, I get the following error:
AttributeError: 'GeoLocationHandlerObj' object has no attribute 'myMethod'.
What am I missing in order to successfully call this method?
I had the same problem, adding two new methods to a previously existing class, trying to call the methods would fail because of "object has no attribute". Finally chased it down to the previous dev using a different tabs/spaces configuration from my editor. Once I changed my new code to use the same configuration as the previous code, Python was able to reference the functions.

Python import class from local folder

I have 2 classes. The first is named test and goes as following:
import textbox
class test:
a=textbox("test")
a.run()
the second class is textbox and goes as following:
class textbox():
def __init__(self, string):
self.string=string
def run(self):
print string
i get this error
File "C:\Users\User\Desktop\edoras\gui\test.py", line 4, in test
a=textbox("test")
TypeError: 'module' object is not callable
I use the pydev eclipse plugin
Try
a = textbox.textbox("test")
or alternatively use
from textbox import textbox
Not sure about the error you mention, but your print statement in text box.run is wrong:
print self.string
You are calling directly the module textbox, which is not allowed.
Maybe it contains an omonymous function? In that case you should call
textbox.textbox('test')
(the first textbox would be the module name, and the second a function inside it)

Categories