I defined a class called Parser in a file called parser.py, that parses a test result....
import sys
import re
class Parser:
def __init__(self):
pass
def udp_parse(self, filename=""):
# ... some code over here
Now, in main.py. I have:
from dbconn import *
from parser import *
import os
import subprocess
def main()
dbconn = Dbconn()
parse = Parser()
# more code here ...
if __name__ == '__main__':
main()
and I'm getting:
Traceback (most recent call last):
File "iperf.py", line 108, in <module>
main()
File "iperf.py", line 49, in main
parse = Parser()
NameError: global name 'Parser' is not defined
parser.py is in the same directory as dbconn.py and main.py. Dbconn() works without any problem, but I'm not understanding why Parser() can't work too ...
Parser is an existing python module. Use a different file name (not parser.py) or insert your path in sys.path before stdlibs.
import sys
sys.path.insert(0,'parser/directory')
from parser import *
Related
I have a class JCheq, with a static var named 'logger'.
JCheq imports module printing_systems, but I need to use JCheq.logger from printing_systems.
My code does not compile after I put import JCheq in printing_systems.py.
jcheq.py
from printing_systems import printing_systems
from logger import logger
class JCheq:
logger = logger.Logger('logs/jcheq.log', loglevel=logger.Logger.INFO)
def __init__(self):
pass
...
printing_systems/printing_systems.py
from jcheq import JCheq
class WinLPR:
def __init__(self):
pass
#staticmethod
def send(spool, params):
temp_dir = tempfile.mkdtemp()
try:
JCheq.logger.log('Creando archivo temporal en dir: ' + temp_dir, logger.Logger.TRACE)
Error trace:
Traceback (most recent call last):
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/jcheq.py", line 12, in <module>
from printing_systems import printing_systems
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/printing_systems/printing_systems.py", line 7, in <module>
from jcheq import JCheq
File "/home/jsivil/Desktop/Proyectos/UNPAZ/jcheq/jcheq/jcheq.py", line 12, in <module>
from printing_systems import printing_systems
ImportError: cannot import name 'printing_systems'
Moving the import statement in the function is commonly used to solve circular imports. It is handy in cases when restructuring your application would be too costly (if useful at all).
Another solution would be to move JCheq.logger into its own module that both jcheq.py and printing_systems/printing_systems.py would import.
Or, you could make logger.Logger a factory function backed by some registry (or simply memoize it) so that it returns the same logger when the same arguments are given. This way, printing_system.py would simple import logger instead of importing jcheq.
collection.py
import sys
import os
import pymongo
from pymongo import MongoClient
class Collection():
"""returns a collection curser from mongodb"""
client = MongoClient()
def __init__(self, db, collection_name):
self.db = db
self.collection_name = collection_name
def getCollection(self):
data_base = getattr(self.client, self.db)
collObject = getattr(data_base, self.collection_name)
return collObject
main.py
import sys
import os
import collection
def main():
pass
if __name__ == '__main__':
print"Begin Main"
agents = Collection('hkpr_restore','agents')
print "agents is" , agents
These files are in the same directory. When I run main.py, however, I get an error:
Begin Main
Traceback (most recent call last):
File "main.py", line 23, in <module>
agents = Collection('hkpr_restore','agents')
NameError: name 'Collection' is not defined
From what I've read, if the files are in the same directory, all I need to do is use import collection.
Am I missing something?
You've only imported collection, not Collection.
Either do from collection import Collection, or use the full qualified name when instantiating: agents = collection.Collection('hkpr_restore','agents').
Why can in Python 3 enum equality not be checked correctly across module boundaries if the enum has been defined in the main module? Here is an example:
moduleA.py:
#!/usr/bin/python3
import moduleB
from enum import Enum, unique
#unique
class MyEnum(Enum):
A = 1
B = 2
# def __eq__(self,other):
# assert isinstance(other,self.__class__)
# return self.value == other.value
if __name__ == "__main__":
myVar = MyEnum.B
moduleB.doStuff(myVar)
moduleB.py:
#!/usr/bin/python3
import moduleA
def doStuff(aVariable):
bVariable = moduleA.MyEnum.B
assert aVariable == bVariable
Calling "./moduleA.py" on the command line yields:
Traceback (most recent call last):
File "./moduleA.py", line 17, in <module>
moduleB.doStuff(myVar)
File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff
assert aVariable == bVariable
AssertionError
Uncommenting the custom equality operator in the enum leads to an assertion failure there. I've found that the class module is not the same in both cases, as it is "__main__" in one case.
What is the most "Pythonic way" to fix this problem (other than moving the enum to its own module)?
EDIT: Switching to "aVariable is bVariable" does not work either:
Traceback (most recent call last):
File "./moduleA.py", line 17, in <module>
moduleB.doStuff(myVar)
File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff
assert aVariable is bVariable
AssertionError
As far as Python is concerned, you have three modules here:
__main__
moduleA
moduleB
The file you run from the command line, the main entry point, is always stored as the __main__ module. If you import moduleA anywhere in the code, Python sees that as separate from the __main__ module and creates instead a new module object. You thus have two separate MyEnum classes:
__main__.MyEnum
moduleA.MyEnum
Their members are distinct and thus cannot be equal.
Your test passes if instead of using import moduleA you used import __main__ as moduleA, or used a separate script file to drive the test; that separate file would become __main__:
#!/usr/bin/python3
# test.py, separate from moduleA.py and moduleB.py
import moduleA
import moduleB
if __name__ == "__main__":
myVar = moduleA.MyEnum.B
moduleB.doStuff(myVar)
Another workaround would be to tell Python that __main__ and moduleA are the same thing; before importing moduleA (or moduleB, which imports moduleA) you can add another entry to sys.modules:
if __name__ == '__main__':
import sys
sys.modules['moduleA'] = sys.modules['__main__']
import moduleB
I'd not consider this very Pythonic.
This is what a.py looks
import sys
def test_import(another_python_file):
import another_python_file as b
b.run_me()
if __name__ == '__main__':
print sys.argv
test_import(sys.argv[1].strip())
this is what b.py looks
def run_me():
print 'I am script b'
When I run, I get
$ python a.py b.py
['a.py', 'b.py']
Traceback (most recent call last):
File "a.py", line 10, in <module>
test_import(sys.argv[1].strip())
File "a.py", line 5, in test_import
import another_python_file as b
ImportError: No module named another_python_file
What I need?
I would expect it to import b.py and print I am script b
What am I missing?
a.py:
import os
import sys
def test_import(another_python_file):
b = __import__(another_python_file)
b.run_me()
if __name__ == '__main__':
print sys.argv
test_import(sys.argv[1].strip('.py'))
b.py
def run_me():
print 'I am script b'
$ python a.py b.py
['a.py', 'b.py']
I am script b
I was able to do that referring to http://www.diveintopython.net/functional_programming/dynamic_import.html
If you don't need flexibility, you can simply use __import__('module_name'). If you need advanced features like cache control, module searching or reloading, use the imp module.
I am trying to import the class PBase which is in base.py(its in the same folder)
So I am doing the following
from base import PBase
but I am getting the following error
Traceback (most recent call last):
File "test_pricing.py", line 9, in <module>
from base import PBase
ImportError: cannot import name PBase
here is my base.py
import yaml
import unittest, time, re
class PBase(unittest.TestCase):
def enter_credentials(self, username, password):
self.driver.find_element_by_id("id_username").clear
self.driver.find_element_by_id("id_username").send_keys(username)
self.driver.find_element_by_id("id_password").clear
self.driver.find_element_by_id("id_password").send_keys(password)
self.driver.find_element_by_css_selector("input.btn.btn-success").click()
def get_credentials(self):
with open('credentials.yml', 'r') as f:
doc=yaml.load(f)
return doc
def is_user_logged_in(self):
f= "Account" in self.driver.find_element_by_css_selector(".navbar").text
return f
def log_in_user(self):
self.driver.get(self.login_url)
user_dict=self.get_credentials()
username=user_dict["user"]["username"]
password=user_dict["user"]["password"]
self.enter_credentials(username, password)
self.assertEqual(self.expected_logged_in_title, self.driver.title)
def wait_for_chat_window(self, timeout=5):
WebDriverWait(self.driver, timeout, poll_frequency=0.1).until(lambda b: b.find_element_by_id('habla_beta_container_do_not_rely_on_div_classes_or_names').is_displayed())
time.sleep(3)
def close_modal_window(self):
driver=self.driver
driver.find_element_by_xpath('//a[#class="close"]').click()
def tearDown(self):
if self.is_final_test==1:
self.driver.quit()
This might be an issue caused by importing in a circular way. For example one tries to import from Bar from bar.py that requires Foo from foo.py that requires Utils that is defined in bar.py:
foo.py:
from bar import Utils
class Foo:
def __init__(self):
print("hello, from Foo")
Utils.do_something()
and bar:
from foo import Foo
class Utils:
#staticmethod
def do_something():
print("done something")
class Bar(Foo):
def __init__(self):
print('Hi, from Bar')
This gives similar issues where one can import bar inside foo.py without any issue, but once one tries to make any reference to the class Utils inside foo.py one gets various errors, for example the previous code results in:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from bar import Bar
File "bar.py", line 1, in <module>
from foo import Foo
File "foo.py", line 1, in <module>
from bar import Utils
ImportError: cannot import name 'Utils' from 'bar' (bar.py)
The issue is easily solved by placing Utils in its own file.