In one file I create a class called Robot, but when I try to create an object of that class in another file it says:'module' object has no attribute 'Robot'
main.py
import robot as rob
robot=rob.Robot()
robot.py
class Robot(object):
def __init__(self):
return 0
def otherFunctions():
return 0
And it says: 'module' object has no attribute 'Robot'.
Where I am making a mistake?
The way your code is written is correct (barring removal you've presumably made for conciseness)
When you import, Python checks sys.path for importing locations, and imports the first robot it can find.
A couple ways to solve this:
import robot
print robot.__file__
in robot.py
print("hello!")
import sys
sys.path.insert('/path/to/correct/robot/')
import robot
It seems like the syntax in your robot.py file is not correct. You can correct the errors in the most direct way by changing your robot.py file to look like this:
class Robot(object):
def __init__(self):
pass
def other_functions(self):
pass
Note that I used snake casing for the other_functions function. Don't use camelCasing in Python. It's not idiomatic. Also, I added a self argument to other_functions so you won't get a TypeError if you try to invoke it off of a Robot instance.
Also, unless your code is truly as simple as you present it, the error might be coming from a circular import. Make sure you're not trying to import the two modules from each other before they've had a chance to fully execute.
Related
I am trying to use typing in Python 3.8 and I am a bit stuck.
Example: I am mainly developing in main.py. I also have a class util.py that contains some helper functions an classes. But these classes also need to import classes from main.py for Typing. Now, when I want to use functions from util.py in main.py I also need to import it - but then I'll get an error because of circular importing (and rightly so).
Is there a way around this?
Thanks in advance!
Circular imports are not an immediate error in Python; they're only an error if you use them in a particular way. I believe you're looking for forward references
Example main.py:
import util
class SomeClass:
pass
Example util.py
import main
# We can't use main.SomeClass in the type signature because of the cycle,
# but we can forward reference it, which the type system understands.
def make_some_class() -> "main.SomeClass":
return main.SomeClass()
Sylvio's answer is correct, but I want to address just for typing in your title.
Importing classes just for typing in python?
If the only reason you are importing a class is to address some typing consideration, you can use the typing.TYPE_CHECKING constant to make that import conditional.
Quoting that documentation:
Runtime or type checking?
Sometimes there's code that must be seen by a type checker (or other static analysis tools) but should not be executed. For such situations the typing module defines a constant, TYPE_CHECKING, that is considered True during type checking (or other static analysis) but False at runtime. Example:
import typing
if typing.TYPE_CHECKING:
import expensive_mod
def a_func(arg: 'expensive_mod.SomeClass') -> None:
a_var = arg # type: expensive_mod.SomeClass
...
(Note that the type annotation must be enclosed in quotes, making it a "forward reference", to hide the expensive_mod reference from the interpreter runtime. In the # type comment no quotes are needed.)
Bottom line is that you may very well not have to import it all, except for when you are type-checking.
I think the best way to prevent that is to move every class in their own file, and import them where you need them.
Declaring multiple class in a single file is not good for code maintenance and can make big application harder to debug.
And I don't think you can avoid circular importing the way you describe it, if every class depends on each other
I am not too far into python yet and here is the case.
Say I have one python file called functions.py which holds a class with my functions. Below is an example.
import json
class Functionalities:
def addelement(element):
# code goes here`
And I have another python file, kind of 'executable' script which does all the job using functions from functions.py class
Adding from . import functions doesn't help.
How to I call functions from the class from another file?
Unlike java, you don't have to use classes in python. If a class is used only as a holder for functions, chances are that you want a free function (one without a class) instead.
But to answer your actual question, you can use the import statement. That will run the other .py file, and make the namespace available so you can call things defined there.
functions.py:
import json
class Functionalities:
def addelement(element):
# code goes here`
main.py:
import functions
f = functions.Functionalities()
f.addelement('some element')
I am new to Python programming language in general, as well as Python's unittest and unittest.mock system library packages. I am trying to write an unit test to test out an instance method (System under Test) for a Python custom class that I wrote. The module where this class resides, has a bunch of imports. I am trying to mock these imports but I am unable to do so. I have been reading lots of sample test examples as well as read python docs for unittest.mock library, but still unable to get it to work. I would sincerely appreciate any pointers, to get me going.
Here is the concise code summary of what I am trying to do.
The Package Structure:
loader
extract
extract_data.py
utils
dbpool.py
test
test_extract.py
Here is the code that matters.
extract_data.py
from ..utils import dbpool as dbpool
class ExtractService:
def __init__(self):
self.conn = dbpool.get_connection()
def nvl(self, value):
if value and value.strip():
return value.strip()
else:
return 'null'
dbpool.py
def get_connection():
pool = SimpleConnectionPool() # left out the full defn for simplicity
return pool.getconn()
test_extract.py
from loader.extract.extract_data import ExtractService
class TestExtractService:
def test_extract(self):
service = ExtractService() # test fails here as it is trying to initialize the object by invoking __init__ method which inturn looks for a reference to dbpool module
assert service.nvl(' ') == 'null'
assert service.nvl(' SO Rocks ') == 'SO Rocks'
When I run the test, the test will try to get a real connection which I definitely do not want. So, I am trying to mock the import dbpool on the extract_data.py, and wanted to patch my own get_connection function.
I spent so many hours trying to get this to work using multiple combinations of #patch and #patch.object decorators but nothing seems to work. I am actually lost on how to do this. I am not even sure, if I am going down the right path and unfortunately, I do not know any python experts personally to check where I am going wrong. I would really appreciate if the experts here can point me to the right direction.
Thanks,
(There are many similar and more generic questions, been trying the solutions from them after reading through them, can't get them working so asking here as a more situation-specific version of what I'm seeing)
I think I am really miss-understanding how Python does OOP due to my more C#/C++ background. So here's what I'm trying to do right this moment.
I'm starting with two modules to set up the rest of my project, partially as a sanity-check and proof-of-concept. One module logs things to a file as I go while also storing data from multiple modules (to eventually package them all and dump them on request) Doing all this in PyCharm and mentioning the error warnings it suggests by the way, and using Python 2.7
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter():
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
__builtin__.mylogger = LogHelpers
Module 2:
src\ULTs\myULTs.py
mylogger.myLog.classEnter()
(both the modules and the root src\ have an empty init.py file in them)
So according to the totally awesome response here ( Python - Visibility of global variables in imported modules ) at this stage this should be working, but 'mylogger' becomes an 'unresolved reference'
So that was one approach. I also tried the more straight forward global one ( Python: How to make a cross-module variable? )
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter(self):
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
mylogger = LogHelpers
__init__.py
__all__ = ['LogHelpers', hexlogger]
from .logHelpers import *
Module 2:
src\ULTs\myULTs.py
from helpers import mylogger
mylogger.myLog.classEnter()
This version gets a "parameter 'self' unfilled" error on the classEnter, which various reports seem to indicate means that mylogger is un-initialized (misleading error code but that's what it seems to mean)
And then I tried this..
Module 1:
src\helpers\logHelpers.py
class LogHelpers:
class log:
def classEnter(self):
#doing stuff
def __init__(self):
self.myLog = LogHelpers.log() #forgot to mention this was here initially
[..] various logging functions and variables to summarize what's happening
__mylogger = LogHelpers
__init__.py
__all__ = ['LogHelpers', hexlogger]
from .logHelpers import *
Module 2:
src\ULTs\myULTs.py
from helpers import mylogger
def someFunction(self):
global mylogger
mylogger.myLog.classEnter()
And this version gets the 'Global variable is undefined at the module level' error when I hover of global mylogger.
Then there is the idea of each other module tracking its own instance of a class apparently, if I end up having to I can go with that method and coordinate them.. but that's kind of a hack considering what I'm trying to do.
That's kind of where I'm at, that's the gist of what I'm trying to do... I'm reading through as many similar questions as I can but all of them seem to come back to these kinda of solutions (which don't seem to be working) or saying 'don't do that' (which is generally good advice but I'm not really grocking the preferred Pythony way of keeping multiple ongoing non-static classes organized for a large project - other than shoving them all in one directory)
Thoughts? (How badly am I mangling Python here?)
[EDIT] Based on feedback tried a mini version that eliminated the inner classes completely:
Ok, so did a local mini-class based on what you said:
class testClass:
def __init__(self):
self.testVar = 2
def incrementVar(self):
self.testVar += 1
myClass = testClass()
Set it up via init.py
__all__ = [myClass]
from .logHelpers import myClass
Went to other module and
from helpers import myClass
class Test_LogHelpers(unittest.TestCase):
def test_mini(self):
myClass.incrementVar()
Ran it directly instead of looking at PyCharm, no Global anything.. NameError: name 'myClass is not defined
So still at square one :( (and still need to store state)
[EDIT] Adding Traceback:
Traceback (most recent call last):
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 124, in <module> module = loadSource(a[0])
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 40, in loadSource module = imp.load_source(moduleName, fileName)
File "C:\[...mylocation...]\py\src\ULTs\LogHelpers_ULT.py", line 3, in <module> from helpers import myClass
File "C:\[...mylocation...]\py\src\helpers\__init__.py", line 7, in <module>
__all__ = [myClass]
NameError: name 'myClass' is not defined
============================================================================
kk, I got it working with the miniclass. I don't know why the other approach / approaches was not working, but this seemed to fix things.
(Resources: http://docs.python-guide.org/en/latest/writing/structure/ , http://mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html )
**logHelpers.py**
[... some static logging functionality ...]
class testClass:
def __init__(self):
self.testVar = 2
def incrementVar(self, source):
self.testVar += 1
mylogger.myLog.info(source + " called, new val: " + str(self.testVar))
myClass = testClass()
**test_LogHelpers_ULT.py**
import unittest
from helpers.logHelpers import myClass
class Test_LogHelpers(unittest.TestCase):
def test_mini(self):
myClass.incrementVar("LogHelpers")
For some reason skipping the
init.py
(and leaving it blank) and going for the explicit importation worked. It also maintained state - I created a duplicate of the test file and my log output correctly had '3' for the first file to call the helper, and '4' for the second file to call the helper.
Thanks Daniel Roseman for the help and suggestions, they had me look a bit more in the right direction. If you can spot why the previous stuff wasn't working it would be much appreciate just to add to my understanding of this language, but I'm gonna go ahead and mark your answer as 'Answered' since it had some very useful feedback.
Before I start, note that the PyCharm warnings are not actual Python errors: if you ran your code, you would probably get more useful feedback (remember static analysis of a dynamic language like Python can only get you so far, many things can't be resolved until you actually run the code).
Firstly, it's really not clear why you have nested classes here. The outer class seems completely useless; you should remove it.
The reason for the error message about "self" is that you have defined an instance method, which can only be called on an instance of log. You could make mylogger (absolutely no need for the double-underscore prefix) an instance: mylogger = log() - and then import that, or import the class and instantiate it where it is used.
So in your first snippet, the error message is quite clear: you have not defined mylogger. Using my recommendation above, you can do from helpers import mylogger and then directly call mylogger.classEnter().
Finally, I can't see what that global statement is doing in someFunction. There's no need to declare a name as global unless you plan to reassign it within your scope and have that reassignment reflected in the global scope. You're not doing that here, so no need for global.
By the way, you should also question whether you even need the inner log class. Generally speaking, classes are only useful when you need to store some kind of state in the object. Here, as your docstring says, you have a collection of utility methods. So why put them in a class? Just make them top-level functions inside the logHelpers module (incidentally, Python style prefers lower_case_with_underscore for module names, so it should be "log_helpers.py").
Can anyone explain how to make the following example work? Since several functions inside of the class will use the same function from platform I thought it would be better to import it right inside of the class, but I don't see how I can use it inside of the function (since I constantly get errors about it).
#!/usr/bin/python
class test:
from platform import system
is_linux(self):
system = system()
if system == "Linux": return True
A better example:
#!/usr/bin/python
# Add ANSI colour strings
class stdout:
from sys import stdout
def message(message, self): stdout.write(message)
Note: This is just a snippet, there are some parts missing but an example of what I mean.
I know I could probably just move system = system() and use self.system but perhaps a better way?
Well, it is not that simple.
Actually, import statement in many aspects looks like direct definition of something in place of it. If you write
class test:
from platform import system
it looks exactly like
class test:
def system():
# ....
and then you have following problems:
you can't use just system() because system is not in global scope
you can't use self.system() because in this form, python automatically passes self as first argument, but system() has no parameters and you'll get TypeError: system() takes no arguments (1 given)
you can't use test.system() because system() looks like a plain method, and you'll get TypeError: unbound method system() must be called with test instance as first argument (got nothing instead)
There are several ways around these problems:
place import platform at top level, and use platform.system() wherever you want, thus fixing issue #1 from prev. list
use staticmethod decorator, fixing issues #2 and #3 from prev. list.
like
class test:
from platform import system
system = staticmethod(system)
then you can use either self.system() or test.system()
Actually, you should just import everything in toplevel and forget about it.
You only have to split import declarations if you need something special for running.
Like
import foo
import bar
def fun(param1, param2):
# .....
if __name__ == '__main__':
from sys import argv
if len(argv) > 2:
fun(argv[1], argv[2])
In this example, moving from sys import argv is valid, because it is needed only when running a script. But when you use it as an imported module, there is no need in this import.
But that is not your case, because in your case, system() is always needed for test class, so there is no reason to move this import from toplevel. Just leave it there and never mind.
I'm surprised no one thought of this:
class test:
def __init__(self):
from platform import system
self.system = system()
def test(self):
return self.system()
d = test()
print d.system()
print d.test()
Just import it up top, before you declare the class. That's where the interpreter expects to see it, and if you tried importing it within a class or other definition, you'd run the risk of running into major scope issues later on.
Alternatively, based on what it seems you're trying to do, you might try subclassing some of the things you're using (which, to dramatically oversimplify, is somewhat like extends in Java.)
Looks like a case of premature optimization!? I think it's not possible to import something inside a class definition. Why do you want to do that? I certain cases it might make sense to import inside a method, but even those are rather rare. Why don't just put the import on top of your file where everybody can see it?