Python import in __init__() - python

I need to have an import in __init__() method (because i need to run that import only when i instance the class).
But i cannot see that import outside __init__(), is the scope limited to__init__? how to do?

Imported names are bound to the current scope, so an import inside a function binds to a local name only.
If you absolutely have to import something in __init__ that then needs to be globally avaliable, mark the imported name as global first:
>>> def foo():
... global sys
... import sys
...
>>> sys
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>> foo()
>>> sys
<module 'sys' (built-in)>
but this usually leads to strange and wonderfully difficult to locate bugs. Don't do that, just make your imports at module scope instead.
If you need the imported name within other class methods, you could also assign the imported name to a instance variable:
class Foo(object):
def __init__(self):
import os
self.join = os.path.join
but again, that's not the best practice to use.

You can just import it again other places that you need it -- it will be cached after the first time so this is relatively inexpensive.
Alternatively you could modify the current global namespaces with something like globals()['name'] = local_imported_module_name.
EDIT: For the record, although using the globals() function will certainly work, I think a "cleaner" solution would be to declare the module's name global and then import it, as several other answers have mentioned.

The import statement makes the imported names only available to the current scope. An import foo inside your __init__ creates a foo which is only visible within the __init__ method.
You could either add the import foo to any method which needs to access the module or if you find yourself writing the import over an over again use the global keyword to import it to the module scope.
class Wayne(object):
def __init__(self):
global foo
import foo

If you want the result of your import to be visible to other objects of the class, you would need to assign the resulting object from your import to a class or instance variable
For example:
>>> class Foo(object):
... def __init__(self):
... import math
... self.bar = math.pi
... def zoo(self):
... return self.bar
...
>>> a = Foo()
>>> a.zoo()
3.141592653589793

Related

Overriding module function after it is imported - Python

Let's say we have three python modules: app.py, commons.py and c.py
commons.py:
def func():
pass
def init(app)
global func
func = app.func
app.py:
import commons
import c
# Doing some initialization so that we are ready to override the function
c.foo()
init(app) # the app object contains a function called func which we wish to overwrite in commons.py
c.foo()
c.py:
from commons import *
def foo():
func()
What i want to accomplish is that the first time c.foo is called, it will do nothing, and the second time it will execute app.func. Every module in my project is dependent on the func in commons.py, and the function has to be declared at runtime as it is attached to an object.
Is there a way to import by reference in python and change the pointer of the function in all modules?
What I've done so far is to have an init function in every module and simply overwrite empty lambda functions, but this seems to be a poor solution.
You can achieve this with a further level of indirection:
commons.py
def normalFunc():
pass
def func():
normalFunc()
def init(app)
global normalFunc
normalFunc = app.func
This works, because any other module which has the normal: from commons import foo and foo() still calls the same foo().
Its just that the internals of foo() change each time that the init() function is called.

Importing a module for all methods of an instance in Python3

I encountered a problem whilst importing a module in a Python3 class:
I am importing a module in the __init__ method of my class. It works fine in this method, however is there a way to use this module again in another method? I tried saving the module into a self. variable, still doesn't work.
Of course I could import it again inside the method, but I would rather import the module for all of my methods, since most of them need it.
I'll give you some example code below:
class Example(object)
def __init__(self):
import moduleName as module
module.function() # works perfectly
# Trying to save module for the whole instance:
self.module = module
def method(self):
module.function() # Does not recognize module
self.module.function() # Does not recognize attribute either
I'd be happy if someone could help me with this:)
I don't know if in python we can save a module in a variable. I attempt to declare the import at class level, but the code doesn't work.
I python the function are first-citizen so we can save function in a variable. You should save the function you need in variables when you are in __init__():
import module as mod
mod.function()
self.function = mod.function
After a while...
You can load a module dinamically, but to this you have to import the module importlib. This is the code:
import importlib
class MyClass:
def __init__(self):
self.module = importlib.import_module("module")
self.module.function()
def func(self):
self.module.function()
c = MyClass()
c.func()
There is also the imp module.

What is the right way to import modules inside my class

I am new to python and I'm trying to add math module inside my class but I don't know what is the right way adding it
import math
class myClass():
#some code
or
class myClass():
import math
#some code
What is the right way the first or the second one?
Anything declared inside a class definition becomes a class variable, a module included, so by importing math within a class definition, it becomes a class variable that is accessible only via the class object or the instance object, so:
class myClass:
import math
def __init__(self, value):
self.value = value
def sqrt(self):
return math.sqrt(self.value)
print(myClass(4).sqrt())
would result in:
NameError: name 'math' is not defined
but changing the sqrt method to:
def sqrt(self):
return self.math.sqrt(self.value)
would properly output:
2.0
That said, there is usually no good reasons to import modules as class variables. In the vast majority of cases modules are imported outside the class, as global variables.

Is it possible to import a class defined inside a function?

There is a class from a 3rd party system that I'd like to sub-class for my own purposes, but it's defined within a function, like so:
def foo():
class Bar():
return Bar
If I try to import it just with from x import bar, I get ImportError: cannot import name 'Bar'. Is it possible (or wise) to import Bar? Perhaps the original coder put the class inside the function specifically to prevent others from using it directly?
The class I'm trying to get is CookieSession, defined inside BaseCookieSessionFactory, which can be found here:
http://docs.pylonsproject.org/projects/pyramid/en/master/_modules/pyramid/session.html
It already does 90% of what I want, and it seems like it would be a waste to implement my own from scratch, since I would just be copy-pasting much of the code.
Edit:
Following the advice in Chepner's answer, I sub-classed it by building my own factory function:
from pyramid.session import SignedCookieSessionFactory
def MySessionFactory(secret, [other args here...]):
#implementer(ISession)
class MySession(SignedCookieSessionFactory(secret)):
...
return MySession
You can't import it, because it doesn't exist until foo is actually called. However, it appears that foo simply defines the function and returns a reference to it. In that case, you just need something like
from otherfile import foo
Bar = foo()
x = Bar() # create an instance of Bar

How does Python handle imported subclasses?

I am working on a project that requires me to build several classes and subclasses in one file, and use them in a second file. I would like to ask how Python handles importing the first file into the second.
For instance, if i have a file my_classes.py:
class Myclass(object):
pass
class Mysubclass(myclass):
pass
will using the following code work:
from my_classes import Myclass
print Mysubclass
(where the print command is just an example of using Mysubclass), or do I need to import Mysubclass explicitly?
Thanks in advance!
This won't work. Python import statement doesn't care about subclasses. Actually, it doesn't care about anything. It does precisely what you tell it to do. "Explicit is better than implicit" is a popular saying in Python circles.
Here:
from my_classes import Myclass
You told Python to import only Myclass.
This will import both classes:
from my_classes import Myclass, Mysubclass
You can read how Python import works here.
Your subclass will not be available if you do it like this. You must import every object by itself.
Here a quick example
test_class.py
class MyClass(object):
def init(self):
print self.class
class MySubClass(MyClass):
def __init__(self):
print self.__class__
test_class_import.py
from test_class import MyClass
MyClass()
MySubClass()
##output##
<class 'test_class.MyClass'>
Traceback (most recent call last):
File "test_class2.py", line 4, in <module>
MySubClass()
NameError: name 'MySubClass' is not defined
but
from test_class import MyClass, MySubClass
MyClass()
MySubClass()
##output##
<class 'test_class.MyClass'>
<class 'test_class.MySubClass'>
Every module has a namespace.
A namespace is a mapping from variable names to values (Python objects).
The statement
import my_classes
makes the my_classes namespace accessible from the current module by placing the variable name my_classes in the current module's namespace. You can then access values from my_classes with the syntax
my_classes.variable
So, for example:
import my_classes
print my_classes.Mysubclass
print my_classes.MyClass
If that is too much typing, I suggest
import my_classes as MC
print MC.Mysubclass
print MC.MyClass
you could also do
from my_classes import Mysubclass, MyClass
but this form of import is discouraged by some Python experts.
from my_classes import Mysubclass, MyClass
loads the entire module my_class but only
places the variable names Mysubclass and MyClass in the current module's namespace. They point to the same values as do the variables of the same name in the my_classes namespace. You don't get access to anything else from the my_class module's namespace.

Categories

Resources