Problem with import in Python - python

[Closing NOTE]
Thank you everyone that trying to help me.
I've found the problem and it have nothing to do with python understanding of mine (which is little). :p
The problem is that I edit the wrong branch of the same project, Main.py in one branch and XWinInfos.py in another branch.
Thanks anyway.
[Original Question]
I am a Java/PHP/Delphi programmer and only use Python when hack someone else program -- never to write a complex Python myself. Since I have a short free time this week, I determine to write something non-trivia with Python and here is my problem
First I have python files like this:
src/
main.py
SomeUtils.py
In "SomeUtils.py, I have a few functions and one class:
...
def funct1 ...
def funct2 ...
class MyClass1:
__init__(self):
self. ....
...
Then in "main.py", I use the function and class:
from SomeUtils import *;
def main():
funct1(); # Use funct1 without problem;
aMyObj1 = MyClass1(); # Use MyClass1 with error
if (__name__ == "__main__"):
main();
The problem is that the functions are used without any problem what so ever but I cannot use the class.
The error is:
NameError: global name 'MyClass1' is not defined
What is the problem here? and What can I do?
EDIT: Thanks for answers for I still have problem. :(
When I change the import statements to:
from SomeUtils import funct1
from SomeUtils import MyClass1
I have this error
ImportError: cannot import name MyClass1
EDIT 2:----------------------------------------------------------
Thanks you guys.
I think, it may be better to post the actual code, so here it is:
NOTE: I am aware about ";" and "(...)" but I like it this way.
Here is the dir structure.
DIRS http://dl.getdropbox.com/u/1961549/images/Python_import_prolem_dir_.png
as you see, I just add an empty init.py but it seems to make no different.
Here is main.py:
from XWinInfos import GetCurrentWindowTitle;
from XWinInfos import XWinInfo;
def main():
print GetCurrentWindowTitle();
aXWinInfo = XWinInfo();
if (__name__ == "__main__"):
main();
Here is XWinInfos.py:
from subprocess import Popen;
from subprocess import PIPE;
from RegExUtils import GetTail_ofLine_withPrefix;
def GetCurrentWindowID():
aXProp = Popen(["xprop", "-root"], stdout=PIPE).communicate()[0];
aLine = GetTail_ofLine_withPrefix("_NET_ACTIVE_WINDOW\(WINDOW\): window id # 0x", aXProp);
return aLine;
def GetCurrentWindowTitle():
aWinID = GetCurrentWindowID();
aWinTitle = GetWindowTitle(aWinID);
return aWinTitle;
def GetWindowTitle(pWinID):
if (aWinID == None): return None
aWMCtrlList = Popen(["wmctrl", "-l"], stdout=PIPE).communicate()[0];
aWinTitle = GetTail_ofLine_withPrefix("0x[0-9a-fA-F]*" + aWinID + "[ ]+[\-]?[0-9]+[ ]+[^\ ]+[ ]+", aWMCtrlList);
return aWinTitle;
class XWinInfo:
def __init__(self):
aWinID = GetCurrentWindowID();
self.WinID = pWinID;
self.Title = GetWindowTitle(pWinID);
The file RegExUtils.py holds a function "GetTail_ofLine_withPrefix" which work fine so.
If I use "from XWinInfos import *;", the error goes "NameError: global name 'XWinInfo' is not defined".
If I use "from XWinInfos import XWinInfo;", the error goes "ImportError: cannot import name XWinInfo".
Please helps.
Thanks in advance.

Hmm... there's several typos in your example, so I wonder if your actual code has some typos as well. Here's the complete source from a quick test that does work fine without import errors.
SomeUtils.py:
def funct1():
print('Function 1')
def funct2():
print('Function 2')
class MyClass1(object):
def __init__(self):
print('MyClass')
main.py:
from SomeUtils import *
def main():
funct1()
aObj = MyClass1()
if (__name__ == "__main__"):
main()
[EDIT Based on OP additional info]
I still can't recreate the same error, but the code you posted won't initially work for at least a couple of errors in the XWinInfox.py init method:
self.WinID = pWinID #change to 'aWinID' since pWinID is not defined
self.Title = GetWindowTitle(pWinID) #change to 'aWinID'since pWinID is not defined
so a corrected version would read:
self.WinID = aWinID
self.Title = GetWindowTitle(aWinID)
Also, you have a typo in your init file name, there should be two underscores before AND after the 'init' word. Right now you have '__init_.py' and it should be '__init__.py', however this shouldn't keep your code from working.
Because I don't have the RegExUtils.py code, I just stubbed out the methods that rely on that file. With the stubbed methods and correcting the aforementioned typos, the code you post now works.

why are you importing from XWinInfos? you should be importing from SomeUtils. Not to mention that *-style imports are discouraged.
Edit: your error
ImportError: cannot import name MyClass1
basically tells you that there is no MyClass1 defined in the SomeUtils. It could be because you have another SomeUtils.py file somewhere on the system path and it being imported instead. If that file doesn't have MyClass1, you'd get this error.
Again: it's irrelevant whether you class MyClass1 exist. What might be the case is that you have another XWinInfos.p(y|o|w) somewhere on your system and it's being imported. Otherwise: norepro.

You may want to rewrite main.py as follows:
import SomeUtils as util
def main():
util.funct1() # Use funct1 without problem;
aMyObj1 = util.MyClass1() # Use MyClass1 with error
if __name__ == "__main__":
main()
A few quick notes:
There is no need for semicolons in
Python unless you have more than one
statement on a line
There is no need
to wrap conditional tests in
parentheses except for grouping
from
module import * is discouraged as it
pollutes the global namespace

I suppose you mean
from SomeUtils import *
however, that does not trigger the error for me. This works fine for me:
SomeUtils.py
def funct1():
print 4
class MyClass1:
def __init__(self):
print 8
main.py
from SomeUtils import *
def main():
funct1() # Use funct1 without problem;
aMyObj1 = MyClass1() # Use MyClass1 without error
if (__name__ == "__main__"):
main()

Your question is naturally linked to a lot of SO older one.
See, just for reference, SO1342128 and SO1057843

Related

class declaration in exec inits class, but functions don't work

I am going to attach two blocks of code, the first is the main code that is ran the second is the testClass file containing a sample class for testing purposes. To understand what's going on it's probably easiest to run the code on your own. When I call sC.cls.print2() it says that the self parameter is unfulfilled. Normally when working with classes, self (in this case) would be sC.cls and you wouldn't have to pass it as a parameter. Any advice is greatly appreciated on why this is occuring, I think it's something to do with exec's scope but even if I run this function in exec it gives the same error and I can't figure out a way around it. If you'd like any more info please just ask!
import testClass
def main():
inst = testClass.myClass()
classInfo = str(type(inst)).split()[1].split("'")[1].split('.')
print(classInfo)
class StoreClass:
def __init__(self):
pass
exec('from {} import {}'.format(classInfo[0], classInfo[1]))
sC = StoreClass()
exec('sC.cls = {}'.format(classInfo[1]))
print(sC.cls)
sC.cls.print2()
if __name__ == '__main__':
main()
class myClass:
def printSomething(self):
print('hello')
def print2(self):
print('hi')

How to import local variables of a file to current module

I have this function in my module MetaShrine.py
I am not able to use the local variable first_name_signup.
The error is
NameError: name 'first_name_signup' is not defined
I don't want to make each and every variable global.
Is there a way I can import local variable of another file without making it global?
This is one of my functions in my main module MetaShrine.py
def creating():
first_name_signup = input("Enter Your First Name\n")
password_signup = input("Creat a Password\n")
When I import this module to a new module, using:
from MetaShrine import *
class test(unittest.TestCase):
def test_creating(self):
self.assertIsInstance(first_name_signup, str)
if __name__ == "__main__":
unittest.main()
... I get this:
NameError: name 'first_name_signup' is not defined
Basically, return the value and put it in another variable in the other file. That's the best way I can think of.
def creating():
first_name_signup = input("Enter Your First Name\n")
password_signup = input("Creat a Password\n")
return first_name_signup, password_signup
Second file:
import MetaShrine
class test(unittest.TestCase):
def test_creating(self):
first_name_signup, password_signup = MetaShrine.creating()
self.assertIsInstance(first_name_signup, string)
if __name__ == "__main__":
unittest.main()
i think it was a bad idea to write code in such way. i should have seperated userinput from the functions. putting userinputs on frontend and operations on backend will allow the program to be easily testable.
that is what i did later
I guess the right and pythonic way to write Unit tests in python is to import your classes, methods and functions from your actual module and then run your tests on the imported objects rather than actually importing the return values or variables from the module.
So in your case it should look like
code.py
def creating():
first_name_signup = input("Enter Your First Name\n")
password_signup = input("Creat a Password\n")
return first_name_signup, password_signup
tests.py
import MetaShrine import creating
import unittest
class test(unittest.TestCase):
def test_creating(self):
# actual assert statement for the test case, i.e.
result, _ = creating()
self.assertEqual(result, 'some_name')
if __name__ == "__main__":
unittest.main()

Monkey patch a python function - issue

I'm in trouble replacing a python function from a different module with a TestClass
I'm trying to test a part of my code that contains the function in a module; more in details I would like monkey patch this function.
So, the situation is similar to the following:
Function in the module
def function_in_module():
# do some stuff
return 'ok'
Part of my code that I would like testing
from dir_1.dir_2.dir_3.module_name import function_in_module
class ExampleClass():
def __init__(self):
# do some stuff
self.var_x = function_in_module()
# do some stuff again
Test class
from dir_1.dir_2.dir_3 import module_name
class TestClass(TestCase):
de_monkey = {}
mp = None
def setUp(self):
# save original one
self.de_monkey['function_in_module'] = module_name.function_in_module()
if self.mp is None:
self.mp = MP()
def tearDown(self):
# rollback at the end
module_name.function_in_module = self.de_monkey['function_in_module']
def test_string(self):
module_name.function_in_module = self.mp.monkey_function_in_module
test_obj = ExampleClass()
self.assertEqual(test_obj.var_x, 'not ok')
class MP(object):
#staticmethod
def monkey_function_in_module(self):
return 'not ok'
As the assert statement shows, the expected result is 'not ok', but the result is 'ok'.
I have debugged about this and seems that the different way to call the functions is the reason because this monkey patch doesn't work.
In fact, if I try to call the function in ExampleClass in this way
self.var_x = module_name.function_in_module()
works correctly.
What am I missing? maybe it's a banality but it's driving me crazy
Thank you in advance
Your code under test imports function_in_module and references it directly. Changing the value of module_name.function_in_module has no effect on the code.
You should replace the function directly in the module that contains the code under test, not in the source module.
Note that your life would be easier if you used the mock library, although the question of where to patch would still be the same.

Threading with Bottle.py Server

I'm having an issue with threading that I can't solve in any way I've tried. I searched in StackOverflow too, but all I could find was cases that didn't apply to me, or explanations that I didn't understand.
I'm trying to build an app with BottlePy, and one of the features I want requires a function to run in background. For this, I'm trying to make it run in a thread. However, when I start the thread, it runs twice.
I've read in some places that it would be possible to check if the function was in the main script or in a module using if __name__ == '__main__':, however I'm not able to do this, since __name__ is always returning the name of the module.
Below is an example of what I'm doing right now.
The main script:
# main.py
from MyClass import *
from bottle import *
arg = something
myObject = Myclass(arg1)
app = Bottle()
app.run('''bottle args''')
The class:
# MyClass.py
import threading
import time
class MyClass:
def check_list(self, theList, arg1):
a_list = something()
time.sleep(5)
self.check_list(a_list, arg1)
def __init__(self, arg1):
if __name__ == '__main__':
self.a_list = arg.returnAList()
t = threading.Thread(target=self.check_list, args=(a_list, arg1))
So what I intend here is to have check_list running in a thread all the time, doing something and waiting some seconds to run again. All this so I can have the list updated, and be able to read it with the main script.
Can you explain to me what I'm doing wrong, why the thread is running twice, and how can I avoid this?
This works fine:
import threading
import time
class MyClass:
def check_list(self, theList, arg1):
keep_going=True
while keep_going:
print("check list")
#do stuff
time.sleep(1)
def __init__(self, arg1):
self.a_list = ["1","2"]
t = threading.Thread(target=self.check_list, args=(self.a_list, arg1))
t.start()
myObject = MyClass("something")
Figured out what was wrong thanks to the user Weeble's comment. When he said 'something is causing your main.py to run twice' I remembered that Bottle has an argument that is called 'reloader'. When set to True, this will make the application load twice, and thus the thread creation is run twice as well.

Is there a way to get the name of the 'parent' module from an imported module?

I'm curious if it's possible to access the name of the parent module that some other module is imported into.
For instance, if I have a module (moduleA) and a parent is module, foo.py, into which it will be imported into, is it possible for moduleA to know where foo is located ?
ModuleA
def print_parent_module():
os.path.asbpath(#somehow access filename of parent module)
foo.py
import moduleA
print moduleA.print_parent_module()
>>> "foo.py"
I ran into a similar issue. You could make use of __name__:
parent_name = '.'.join(__name__.split('.')[:-1])
Or if you try to access the module directly (not the OP's question but related), see my answer in Is there a way to access parent modules in Python
No. Imported modules do not hold any form of state which stores data related to how they are imported.
I think the better question is, why would you even want to do it this way? You're aware that if foo.py is indeed your __main__ then you can easily get the name foo.py out of it (by using sys.argv)? And if foo.py is an imported module instead, then you obviously already know the name of foo.py and its location, etc. at the time that you import it.
Here is something I came with to store a parent's method name and variables to be recalled later in the class with a decorator.
import inspect
from functools import wraps
def set_reuse_vars(method):
#wraps(method)
def _impl(self, *method_args, **method_kwargs):
func_current = inspect.currentframe()
self.recall_func = dict()
self.recall_func['method_kwargs'] = func_current.f_locals['method_kwargs']
self.recall_func['method_name'] = func_current.f_locals['method'].__name__
return method(self, *method_args, **method_kwargs)
return _impl
class APIData(object):
def __init__(self):
self.client = None
self.response = None
self.recall_func = None
def get_next_page(self):
# Takes a pageToken to return the next result
get_func = getattr(self, self.recall_func['method_name'])
self.recall_func['method_kwargs']['pageToken'] = self.response['nextPageToken']
return get_func(**self.recall_func['method_kwargs'])
#set_reuse_vars
def search_list_by_keyword(self, **kwargs):
self.response = self.client.search().list(
**kwargs
).execute()
return self.response
script to run it.
api_data = APIData()
results = api_data.search_list_by_keyword(
part='snippet',
maxResults=25,
order='date')
print(results)
resultsTwo = api_data.get_next_page()
print(resultsTwo)
Figured it out!
A little import statement inside of the function can give access to the module name.
moduleA
def print_module_name():
import sys
return sys.argv[0]
Then, inside the "parent" module
# foo.py
import os
import moduleA
if __name__ == '__main__':
print os.path.split(moduleA.print_module_name())[-1]
Gives:
>>> 'foo.py'

Categories

Resources