Using relative import without from - python-3.x

Instead of:
from .model import Foo, Bar
I would like to:
import .model
This raises a syntax error. Is there a way to do it?

Anything following an import keyword must be a valid Python name as it will be added to your scope under that same name.
Instead, do the following.
from . import model

Related

python 3, can't understand import system

this is such a simple problem but I cant seem to find any direct explanation to this.
in module.py
def foo():
print("foo")
in main.py
import module
foo()
it will result in an error saying that foo is not defined? when i look for the answer online, I can't find anything surprisingly
I'm not planning to use things like
from x import y
just straight up the import system
When you import an external module, it generates a variable named module that contains all classes, functions and variables from the module. To acess 'foo' function you need to first acess the module:
module.foo()
To import 'foo' function you can import everything from the module, like this:
from module import *
Now you can simply do: foo()
You can also set a custom name to the module, like:
import module as M
And now you can run 'foo' like this:
M.foo()
PS: I'm not english native
The statement
import module
makes the name of module module available. So you can use module.foo().
If you want to call foo() without "qualifying" it:
from module import foo
or
from module import *
but that latter is bad idea because you are liable to import unexpected names, which may collide with other names you imported from other modules.
from model import foo
is the preferred way as in any kinds of
from model import *
you (and anyone ever working on that code) has no idea what has been imported. Could even lead to name conflicts.

Python: cannot find reference to class when using import

I am new to python. I am using the anaconda prompt to run my code. I am trying to import a class from another module but I keep getting errors such as cannot find reference to the class.
P.S please don't negative mark this, or else I will lose the privilege of asking questions
I have already provided an __init__ function.
The module itself runs just fine.
I have used from parser import Parser
I have used from parser import * statement as well
My Parser class
class Parser(object):
def __init__(self, tokens):
self.tokens = tokens
self.token_index = 0
My main class
from parser import Parser
I expected it to normally import the class, but it is unable to.
I keep getting the cannot import name 'Parser' from 'parser' (unknown location) when I use from parser import Parser
parser is also the name of a Python module in the standard library.
It's likely there is a name conflict, and that Python is importing the module from the standard library.
I changed the module name to mparser and it works!

How to import function from a module given absolute path?

from bar import foo
allows one to import function foo from module bar, without importing the whole module.
Now, this thread: Python 3.4: How to import a module given the full path? shows different methods to import a module given it's full path depending on python's version.
Is their a way to import function foo from module bar given the absolute path of bar and without importing whole module bar ?
Thanks in advance for any tips
No, there is no such way.
That said...
from bar import foo
Is also importing the whole module bar
it is like:
import bar
foo = bar.foo
del globals['bar']

Why I can't import modules whose names include blank space in Python3? [duplicate]

Do I have to take out all the spaces in the file name to import it, or is there some way of telling import that there are spaces?
You should take the spaces out of the filename. Because the filename is used as the identifier for imported modules (i.e. foo.py will be imported as foo) and Python identifiers can't have spaces, this isn't supported by the import statement.
If you really need to do this for some reason, you can use the __import__ function:
foo_bar = __import__("foo bar")
This will import foo bar.py as foo_bar. This behaves a little bit different than the import statement and you should avoid it.
If you want to do something like from foo_bar import * (but with a space instead of an underscore), you can use execfile (docs here):
execfile("foo bar.py")
though it's better practice to avoid spaces in source file names.
You can also use importlib.import_module function, which is a wrapper around __import__.
foo_bar_mod = importlib.import_module("foo bar")
or
foo_bar_mod = importlib.import_module("path.to.foo bar")
More info: https://docs.python.org/3/library/importlib.html
Just to add to Banks' answer, if you are importing another file that you haven't saved in one of the directories Python checks for importing directories, you need to add the directory to your path with
import sys
sys.path.append("absolute/filepath/of/parent/directory/of/foo/bar")
before calling
foo_bar = __import__("foo bar")
or
foo_bar = importlib.import_module("foo bar")
This is something you don't have to do if you were importing it with import <module>, where Python will check the current directory for the module. If you are importing a module from the same directory, for example, use
import os,sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
foo_bar = __import__('foo_bar')
Hope this saves someone else trying to import their own weirdly named file or a Python file they downloaded manually some time :)

Mutual imports; difference between import's standart, "from" and "as" syntax

Given this simple folder structure
/main.py
/project/a.py
/project/b.py
main.py is executed by the python interpreter and contains a single line, import project.a.
a and b are modules, they need to import each other. A way to achieve this would be
import project.[a|b]
When working with deeper nested folder structures you don't want to write the entire path everytime you use a module e.g.
import project.foo.bar
project.foo.bar.set_flag(project.foo.bar.SUPER)
Both from project import [a|b] and import project.[a|b] as [a|b] result in an import error (when used in both, a and b).
What is different between the standart import syntax and the from or as syntax? Why is only the standart syntax working for mutual imports?
And more importantly, is there a simple and clean way to import modules that allows mutual imports and assigning shorter names to them (ideally the modules basename e.g. bar in the case of project.foo.bar)?
When you do either import project.a or from project import a, the following happens:
The module object for project.a is placed into sys.modules. This is a dictionary that maps each module name to its module object, so you'll have sys.modules = {..., 'p.a': <module 'p.a' from '.../project/a.py'>, ...}.
The code for the module is executed.
The a attribute is added to project.
Now, here is the difference between import project.a and from project import a:
import project.a just looks for sys.modules['project.a']. If it exists, it binds the name project using sys.modules['project'].
from project import a looks for sys.modules['project'] and then checks if the project module has an a attribute.
You can think of from project import a as an equivalent to the following two lines:
import project.a # not problematic
a = project.a # causes an error
That why you are seeing an exception only when doing from project import a: sys.modules['project.a'] exists, but project does not yet have a a attribute.
The quickest solution would be to simply avoid circular imports. But if you can't, then the usual strategies are:
Import as late as possible. Suppose that your a.py looks like this:
from project import b
def something():
return b.something_else()
Rewrite it as follows:
def something():
from project import b
return b.something_else()
Of course, you would have to repeat imports in all your functions.
Use lazy imports. Lazy imports are not standard feature of Python, but you can find many implementations around. They work by using the "import as late as possible" principle, but they add some syntactic sugar to let you write fewer code.
Cheat, and use sys.modules, like this:
import sys
import project.a
a = sys.modules['project.a']
Very un-pythonic, but works.
Obviously, whatever solution you choose, you won't be able to access the attributes from a or b until the modules have been fully loaded.

Resources