Importing python module, through __init__.py script - python

My directory structure is
app.py
lib
__init__.py
_foo.py
Inside __init__.py I have written
from . import _foo as foo
Then inside app.py I try to make a call
from lib.foo import *
but it throws ModuleNotFoundError: No module named 'lib.foo' exception.
Basically I want to import everything from _foo.py, through the __init__.py script.
While I realize the code works if _foo.py is renamed into foo.py,
I still wonder if there is any way to make import work through __init__.py.

Not sure about hacking around the import statements, but you could get away with something less explicit like this:
lib/__init__.py
from . import _foo as foo
__all__ = ['foo']
lib/_foo.py
__all__ = [
'test'
]
test = 1
>>> from lib import *
>>> foo
<module 'lib._foo' from '/path/to/test/lib/_foo.py'>
>>> foo.test
1
>>>
EDIT: You could achieve something more explicit by updating sys.modules at runtime:
app.py
import sys
from lib import _foo
sys.modules['lib.foo'] = _foo
lib/_foo.py
test = 1
keep lib/__init__.py to make lib a module
After importing app lib.foo will be an available module
>>> import app
>>> from lib import foo
>>> foo
<module 'lib._foo' from '/path/to/test/lib/_foo.py'>
>>> foo.test
1

Related

How to access a method from pytest, if there's no explicit root package or module

Simply speaking, I have this directory structure:
src/
my_file1.py
tests/
__init__.py
my_file1_test.py
In my_file1.py:
def my_func1(a):
return a + 99
How do I then access my_func1 from the tests? In my_file1_test.py I can't access the method:
# from ??? import ?? # is this needed at all?
def my_test1():
res = my_func1(123) # unaccessible
assert res = 222
Will I have to create __init__.py in scr directory first?
update1
from src.myfile import my_func1
===>
ModuleNotFoundError: No module named 'scr'
And if I add __init__.py then it'll become:
ImportError: cannot import name 'my_func1' from 'src'
If you run pytest from your project root with
python -m pytest
you then have to import the function, as you guessed, with:
from src.myfile import my_func1

How to import only functions in a script with custom package/module in Python?

I'm building a package and a noticed that when I import the submodules, they include all of the built-ins that I've imported as well. Is there a way to get around this so when I navigate the submodule with tab complete only the functions and objects from the script are present?
For example, when I import examplemodule.submodule to only see function_i_want when I'm navigating the package contents?
Directory structure
examplemodule
| __init__.py
| submodule
| __init__.py
| submodule.py
examplemodule | submodule | submodule.py
from collections import *
def function_i_want():
return True
Here's an example of what I can import from the module:
>>> import examplemodule
>>> from examplemodule import submodule
>>> submodule.
submodule.AsyncGenerator( submodule.MappingView(
submodule.AsyncIterable( submodule.MutableMapping(
submodule.AsyncIterator( submodule.MutableSequence(
submodule.Awaitable( submodule.MutableSet(
submodule.ByteString( submodule.OrderedDict(
submodule.Callable( submodule.Reversible(
submodule.ChainMap( submodule.Sequence(
submodule.Collection( submodule.Set(
submodule.Container( submodule.Sized(
submodule.Coroutine( submodule.UserDict(
submodule.Counter( submodule.UserList(
submodule.Generator( submodule.UserString(
submodule.Hashable( submodule.ValuesView(
submodule.ItemsView( submodule.defaultdict(
submodule.Iterable( submodule.deque(
submodule.Iterator( submodule.function_i_want(
submodule.KeysView( submodule.namedtuple(
submodule.Mapping( submodule.submodule
When you say from x.y import * you are importing everything defined in __all__ from the module y that resides in directory x.
If you'd only like to import a subset of y you can do the following:
Limit what you're importing from your script
from examplemodule.submodule import function_i_want
or
from examplemodule.submodule import (
function_i_want,
other_function_i_want
)
Define __all__ in your __init__.py
__all__ = ['function_i_want', 'other_function_i_want']
what you could do is import just the module e.g.
import examplemodule
examplemodule.submodule
what this does is only calls the function if you write the module first then .submodule. this is also good if you have more than one module

Why does importing symbols from a module also define the module symbol?

Given a trivial Python package with an __init__.py:
$ ls -R foo/
foo/:
__init__.py bar.py
$ cat foo/bar.py
def do_stuff(): pass
$ cat foo/__init__.py
from .bar import *
I'm surprised that foo.bar is defined:
>>> import foo
>>> foo.bar
<module 'foo.bar' from 'foo/bar.pyc'>
My understanding of from x import * is that it doesn't define x in the current scope. For example:
>>> from abc import *
>>> abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined
Why is foo.bar defined in my first example, even though I don't have import bar inside __init__.py?
When you reference it by foo.bar, it is not referencing to bar used in the import statement in __init__.py file, instead it is a reference to bar module/file itself. Even if you remove all the code in __init__.py file, import foo; foo.bar would still work.
If that weren't the case, you wouldn't have been able to do something like this
import foo.bar
Since foo is a package, as it contains __init__ file, hence it's internal files can be referenced directly.

changing namespace of current python script (class with module name)

i have a 2.6 python script and library in the following directory structure:
+ bin
\- foo.py
+ lib
\+ foo
\- bar.py
i would like users to run bin/foo.py to instantiate the classes within lib/foo.py. to achieve this, in my bin/foo.py script i have the following code:
from __future__ import absolute_import
import foo
klass = foo.bar.Klass()
however, this results in:
AttributeError: 'module' object has no attribute 'bar'
ie it thinks that foo is itself rather than the library foo - renaming bin/foo.py to bin/foo-script.py works as expected.
is there a way i can keep the bin/foo.py script and import lib/foo.py?
The current directory is on the path by default, so you need to remove that before you import the other foo module:
import sys
sys.path = [dir for dir in sys.path if dir != '']
Alternatively, prepend the lib directory so that it takes precedence:
import sys
sys.path = ['../lib'] + sys.path
If you just write import foo, it will definitely load the foo module in the current scope. Assuming lib and foo as packages, won't you need to write something like this in order to make it work?
import lib.foo.bar as foobar
klass = foobar.Klass()

Runtime import with with multiple subdirectories in python

what is the best way to perform this type of import in python
file to be imported which is available in location one/ne_one/one_two/"
fielname : two.py
def foo():
print "venkatttt!"
main file : main.py
s = __import__("one.one_one.one_two.two", fromlist=[])
function_class = getattr(s,"one_one")
function_class1 = getattr(function_class,"one_two")
function_class2 = getattr(function_class1,"two")
print s
print function_class
print function_class1
print function_class2
function_class2.foo()
output of this code:
<module 'one' from '/opt/auto/src/ex/one/__init__.pyc'>
<module 'one.one_one' from '/opt/auto/src/ex/one/one_one/__init__.pyc'>
<module 'one.one_one.one_two' from '/opt/auto/src/ex/one/one_one/one_two/__init__.pyc'>
<module 'one.one_one.one_two.two' from '/opt/auto/src/ex/one/one_one/one_two/two.py'>
venkatttt!
i am looking out for the best way to perform this import
From your output, I can see you already have __init__.py files in each subdirectory, therefore, you can simply import them:
$> from one.one_one.one_two.two import foo
$> foo()
If you want a handle for each module, you can import them separately:
$> import one.one_one as function_class
$> import one.one_one.one_two as function_class1
$> import one.one_one.one_two.two as function_class2
Finally, you can also define __all__ in one/__init__.py and let this auto-imports happen automatically when import one is executed.

Categories

Resources