I'm trying to use ncclient for Python.
If I do this it works:
from ncclient import manager
m = manager.connect()
If I do this it fails:
import ncclient
m = ncclient.manager.connect()
The error is AttributeError: 'module' object has no attribute 'manager'.
I don't understand what the difference is. Shouldn't that be the same method either way? Why isn't it?
Importing a module (package) does not automatically import submodule. (Some modules do. For example, importing os module also import os.path)
Replace following line:
import ncclient
with:
import ncclient.manager
to load the submodule manager.
Related
I have a github repo named pandora:
https://github.com/akshkr/pandora-python
In the test_case_refactor branch, I can't use submodules of pandora such as pn.util.misc.seed_everything() gives me the following error.
AttributeError: module 'pandora' has no attribute 'util'
I doubted circular imports so moved every import inside function wherever possible but didn't seem to work. And the test-cases written inside the module are passing.
Can someone tell me what exact issue is causing this AttributeError?
Since misc is a python script and not a module in itself, you need to either import the function itself
from pandora.util.misc import seed_everything
seed_everything()
OR, you can import the misc script from util module
from pandora.util import misc
misc.seed_everything()
Sorry if this is a duplicate, but I couldn't find anything for this specific topic. So here's the question:
In python 3 when you want to import an object from some module you would write something like
from module import object
If you want to specify that the module is in the same diretory as the file you're currently working on, you'd precede the module name with a dot like
from .module import object
What do I have to write in order to import an entire module from within the same directory? Intuitively, I tried
import .module
But this gives me a syntax error.
The correct way is to import the module from the current package, i.e. ..
from . import module
This makes the module available with the name module.
import nibabel
nibabel.processing.resample_to_output(input_img, voxel_size)
AttributeError: module 'nibabel' has no attribute 'processing'
import nibabel
import nibabel.processing
nibabel.processing.resample_to_output(input_img, voxel_size)
Why does the first code fail but the second code work?
Expanding on #juanpa answer in the comments, you can simply consider these as two different modules.
For this
import nibabel
You get the error which suggests that this module does not have an attribute named processing
But for this
import nibabel.processing
It works fine since itself can be considered a module and thus means that processing is not an attribute of nibabel.
So it looks the code that you are trying to run only requires the 2nd import and not the first.
I came around this question and got quite disappointed by how the tensorflow developers try to make the tensorflow directory appear as the actual package, whereas the actual package root is actually tensorflow/python. By using a __init__.py file of the form
from tensorflow.python import *
del python
they try to achieve this goal. This results in some inconsistent behaviour (at least so it seems to me) when working with the package, e.g.
import tensorflow.python # seems to work
tensorflow.python # AttributeError: no attribute 'python'
from tensorflow.python import Session # works as expected
tensorflow.python.Session # AttributeError: no attribute 'python'
from tensorflow import python # works as expected
tensorflow.nn # works as expected
import tensorflow.nn # ImportError: no module 'tensorflow.nn'
tensorflow.nn.tanh # works as expected
from tensorflow.nn import tanh # ImportError: no module 'tensorflow.nn'
Now, I was wondering whether/how it could be possible to avoid most/all of these issues to get a more consistent behaviour. The first set of inconsistencies could be easily resolved by not deleting the python attribute. However, given that the goal would be to make the complete package appear as if it is a sub-package, this might not be entirely satisfactory.
To keep things simple, let's consider the following package structure
package/
__init__.py
api/
__init__.py
code.py
where package/api/code.py looks something like
def a():
return 'alpha'
def b():
return 'bravo'
and package/api/__init__.py would be
import package.api.code
would it be possible to create package/__init__.py so that the following works
import package.api # ImportError: no module 'package.api'
package.api # AttributeError: no attribute 'api'
from package.api import code # ImportError: no module 'package.api'
package.api.code # AttributeError: no attribute 'api'
from package import api # ImportError: cannot import 'api'
package.code # works as expected
import package.code # works as above
package.code.a # works as expected
from package import a # correctly imports function a
I believe that the last four lines of code should give the expected result by adding to sys.modules, but I do not seem to be able to find a way to make import package.api fail.
Would anyone have an idea on how this could be done? Feel free to point me to use-cases that I am overlooking or should consider to achieve the above-mentioned goal.
First of all - I must say that I literally hate "shady" techniques like this. It has a bad effect on various IDE intellisense and makes the library structure less understandable. But still...
If you want the submodule code.py to act as an actual subpackage, you need to create a dummy module:
package/
__init__.py
api/
__init__.py
code.py
code/
__init__.py
Add this in code/__init__py:
from package.api.code import *
And this in package/__init__.py:
from package.code import *
And then this part should work as intended:
import package.code # works as expected
package.code # works as expected
package.code.a # works as expected
from package import a # works as expected
If you further add this to the package/__init__.py:
import package.api
del package.api
You basically disconnect user from accessing package.api, but nothing else, and they can still access the submodule through subpackage using 'from x import y':
import package.api # works
package.api.a() # AttributeError: module 'package' has no attribute 'api'
import package.api.code # works
package.api.code.a() # AttributeError: module 'package' has no attribute 'api'
from package.api import code # works
code.a() # works
from package import api # works
api.code.a() # AttributeError: module 'package.api' has no attribute 'code'
I managed to write something that almost works (in package/__init__.py):
import sys
from package.api import *
for key in sys.modules:
parts = key.split('.')
if len(parts) > 1 and parts.pop(0) == __name__:
subkey = parts.pop(0)
if subkey == 'api' and len(parts) == 0:
sys.modules['.'.join([__name__, subkey])] = None
elif subkey == 'api':
m = sys.modules.pop(key)
sys.modules['.'.join([__name__] + parts)] = m
del api
del sys
The import errors suggest that it is still quite a hack, but apart from that most all of the examples work as specified iff the package has already been loaded once (i.e. if import package or alike has been invoked before running the statements from my question). If the first statement is import package.api, there is thus no ImportError as I would like.
In an attempt to find a solution for this problem, I stumbled upon this answer, which practically leads to the same behaviour with much more elegant code:
import sys
from package import api
# clean up this module
self = sys.modules.pop(__name__)
del self
# this module becomes hidden module
sys.modules[__name__] = api
sys.modules[api.__name__] = None
del api
del sys
However, this still suffers from the problem that if the first import is something like import package.api, no ImportError is thrown.
I have a problem when I try to have a cyclic import in Python 3. I am writing a PyQt4 app and I want to make some object available in the whole app. This way I end up having some files:
index.py
import source.blab as bl
source/blab.py
import source.windows
windows = source.windows.Windows()
source/windows.py
import source.window_clients.main_window
class Windows:
...
source/window_clients/main_window.py
import source.blab
class MainWindow(QWidget):
...
So far, the code works. However, for aesthetic reasons, I would like to change the import command in main_window.py into:
import source.blab as bl
which throws an:
AttributeError: module 'source' has no attribute 'blab'
I am sure, this is related to Circular (or cyclic) imports in Python where they say that one cannot use from a * import b in a cyclic import. Is it the same for import a as b? If so, is there another way to change the name of the imported module?
It seems that this is a known bug that has been fixed now.
The reasons have to do with how the import statement was implemented in the different cases.