Reputation: 5705
I have a Python module file which is actually a class with its associated public and private functions. I want to use the logging module inside the class and inside all the functions. But the issue is if I import only once inside __init__()
the import is not visible in the rest of the functions.Do I have to import it in every function of the class?
What is the best way to import such modules inside a class. I searched various discussions about the same in stackoveflow forums but could not come with something concrete.
Below is my sample class:
class Add:
def __init__(self,no1,no2):
import logging
logging.basicConfig(filename='example2.log',level=logging.INFO)
logging.info("The two parameters passed are {0} and {1}:".format(no1,no2))
self.num1 = no1
self.num2 = no2
def add(self):
logging.debug("Inside add function of Add class")
logging.info("Adding the two class properties")
self.result = self.num1 + self.num2
logging.debug("Exiting add function")
def display(self):
logging.debug("Inside display class")
return self.result
if __name__ == '__main__':
a = Add(10,11)
a.add()
print (a.display)
When I try to run this:
C:\Users\bhatsubh\Desktop\Everything\Codes\Python>python Test.py
Traceback (most recent call last):
File "Test.py", line 21, in <module>
a.add()
File "Test.py", line 10, in add
logging.debug("Inside add function of Add class")
NameError: name 'logging' is not defined
Upvotes: 1
Views: 5320
Reputation: 1786
So the problem here is one of scope. When you import inside a function (which occasionaly, see below) then the scope of that import is limited to inside that function:
def foo():
import a
a.something()
def bar():
a.something() # won't work
instead you should try to always import at the top:
import a
def foo():
a.something()
def bar():
a.something()
you should also come up with a good, maintainable way of ordering your imports.
Now, you can do it inside a function, and you can do funky things like dynamic imports and reflection and all kinds of cool stuff, but 99.9% of the time you don't need to, so adding that kind of complexity detracts from maintainability (which should be your goal).
The good times you do want to do it is to resolve complex cyclic imports, or if you're trying to do something funky with dynamic loading for performance. But when it comes to optimising performance, you should always build it first then see where it is breaking.
Upvotes: 2
Reputation: 4936
You could simply assign it to a variable to it:
class Foo:
def __init__(self):
import logging
self._logging = logging
But I would advise to just import it on the module level. It feels very wrong to attach a module to a member variable of a class.
Another option would be to only store the Logger you are going to use:
class Foo:
def __init__(self):
import logging
self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__)
PS: This is probably not the proper way to create a logger for a class, I've never done it and only improvised it here. Read up on how to do it.
Upvotes: 1