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()
Related
I created two files, and when I run a.py, result is {'1': '1'}, it's correct. however, running b.py, the result is none. How can I get the value of requests from b.py?
a.py:
requests = {}
def set_value():
global requests
requests["1"] = "1"
if __name__ == "__main__":
set_value()
print(requests)
b.py:
import a
def get_value():
print(a.requests)
if __name__ == "__main__":
get_value()
if __name__ == "__main__": means that the code following it will only be executed when the file is called explicitly with python3 filename.py from the command line. Since you are simply importing your file and not executing it, the global variable is never set.
Also, python variables are all "global" variables when declared outside of a function, and the global keyword is only needed when you want to declare a global variable inside of a function.
To fix this, change a.py to the following:
requests = {}
def set_vale():
requests["1"] = "1"
set_vale()
so i've got a problem with my code.
File 1:
class Abc(object):
...
def function1(self):
#do something
def function2(self):
x = input()
return x+1
and now i'm trying to test function 2 so i wrote a test for it and i don't know what i am doing wrong:
from unittest.mock import patch
import unittest
from file1 import *
class TestBackend(unittest.TestCase):
def test_mode_first(self):
self.assertEqual(Abc().funcion1(), 30)
#patch('funcion2.input', create=True)
def test_mode_second(self, mocked_input):
mocked_input.side_effect = ["QWE"]
result = Abc().funcion2()
self.assertEqual(result, 10)
if __name__ == '__main__':
unittest.main()
i get ModuleNotFoundError: No module named 'function2'
so what i am doing wrong in here?
thanks for your help :)
You get ModuleNotFoundError because funcion2 is not a module. patch doc is clear about this:
target should be a string in the form 'package.module.ClassName'. The
target is imported and the specified object replaced with the new
object, so the target must be importable from the environment you are
calling patch() from. The target is imported when the decorated
function is executed, not at decoration time.
This works for me when executed with python3 -m unittest discover from the directory the files are in.
BTW you have a couple of typos in your example, e.g. Abc().funcion2(), note the missing t in funcion2.
Also, try not to use from … import *: https://docs.quantifiedcode.com/python-anti-patterns/maintainability/from_module_import_all_used.html#using-wildcard-imports-from-import
# file1.py
class Abc(object):
def function1(self):
return 30
def function2(self):
x = input()
return x + "1"
# test_file1.py
import unittest
from unittest.mock import patch
from file1 import Abc
class TestBackend(unittest.TestCase):
def test_mode_first(self):
self.assertEqual(Abc().function1(), 30)
#patch('builtins.input')
def test_mode_second(self, mocked_input):
mocked_input.return_value = "QWE"
result = Abc().function2()
self.assertEqual(result, "QWE1")
I am trying to work around a problem I have encountered in a piece of code I need to build on. I have a python module that I need to be able to import and pass arguments that will then be parsed by the main module. What I have been given looks like this:
#main.py
if __name__ == '__main__'
sys.argv[] #pass arguments if given and whatnot
Do stuff...
What I need is to add a main() function that can take argument(s) and parse them and then pass them on like so:
#main.py with def main()
def main(args):
#parse args
return args
if __name__ == '__main__':
sys.argv[] #pass arguments if given and whatnot
main(sys.argv)
Do stuff...
To sum up: I need to import main.py and pass in arguments that are parsed by the main() function and then give the returned information to the if __name_ == '__main_' part.
EDIT
To clarify what I am doing
#hello_main.py
import main.py
print(main.main("Hello, main"))
ALSO I want to still be able to call main.py from shell via
$: python main.py "Hello, main"
Thus preserving the name == main
Is what I am asking even possible? I have been spending the better part of today researching this issue because I would like to, if at all possible, preserve the main.py module that I have been given.
Thanks,
dmg
Within a module file you can write if __name__ == "__main__" to get specific behaviour when calling that file directly, e.g. via shell:
#mymodule.py
import sys
def func(args):
return 2*args
#This only happens when mymodule.py is called directly:
if __name__ == "__main__":
double_args = func(sys.argv)
print("In mymodule:",double_args)
One can then still use the function when importing to another file:
#test.py
import mymodule
print("In test:",mymodule.func("test "))
Thus, calling python test.py will result in "In test: test test ", while calling python mymodule.py hello will result in "In mymodule: hello hello ".
I wanted to mix a config.py approach and ConfigParser to set some default values in config.py which could be overridden by the user in its root folder:
import ConfigParser
import os
CACHE_FOLDER = 'cache'
CSV_FOLDER = 'csv'
def main():
cp = ConfigParser.ConfigParser()
cp.readfp(open('defaults.cfg'))
cp.read(os.path.expanduser('~/.python-tools.cfg'))
CACHE_FOLDER = cp.get('folders', 'cache_folder')
CSV_FOLDER = cp.get('folders', 'csv_folder')
if __name__ == '__main__':
main()
When running this module I can see the value of CACHE_FOLDER being changed. However when in another module I do the following:
import config
def main()
print config.CACHE_FOLDER
This will print the original value of the variable ('cache').
Am I doing something wrong ?
The main function in the code you show only gets run when that module is run as a script (due to the if __name__ == '__main__' block). If you want that turn run any time the module is loaded, you should get rid of that restriction. If there's extra code that actually does something useful in the main function, in addition to setting up the configuration, you might want to split that part out from the setup code:
def setup():
# the configuration stuff from main in the question
def main():
# other stuff to be done when run as a script
setup() # called unconditionally, so it will run if you import this module
if __name__ == "__main__":
main() # this is called only when the module is run as a script
[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