I used "code/optimize imports" in Pycharm and it resulted in this
import logging
import os
import re
import subprocess
from getpass import getpass
from pathlib import Path
import requests
import sys
import time
from bs4 import BeautifulSoup
why is it in this order? why is there a blank line?
Maybe it uses isort (https://pypi.org/project/isort/):
import is before from x import y
Than the imports are sorted alphabetically.
And lastly the imports are grouped by the type of the import. The blank line between your imports is the separator between Python Standard Library imports and Third Party imports.
isort parses specified files for global level import lines (imports
outside of try / except blocks, functions, etc..) and puts them all at
the top of the file grouped together by the type of import:
Future
Python Standard Library
Third Party
Current Python Project
Explicitly Local (. before import, as in: from . import x)
Custom Separate Sections (Defined by forced_separate list in configuration file)
Custom Sections (Defined by sections list in configuration file)
Inside of each section the imports are sorted alphabetically. isort
automatically removes duplicate python imports, and wraps long from
imports to the specified line length (defaults to 79).
Edit:
Group imports by type is recommended also in PEP8 (https://www.python.org/dev/peps/pep-0008/#imports)
Related
I would like to know the purpose of a three-dots symbol aka ellipsis put before the package name in an import statement.
Examples:
sklearn/metrics/_plot/det_curve.py:
import scipy as sp
from .base import _get_response
from .. import det_curve
from .._base import _check_pos_label_consistency
from ...utils import check_matplotlib_support
or this Github issue, where they call it an "ellipsis import" and where the three dots are followed by a space:
from ... import MyContentContentType as __MyContentContentType__
from ... import MyDetectionDetectionGender as __MyDetectionDetectionGender__
Three dots is not the Ellipsis object.
According to the documentation, three dots in a relative import statement means "up two levels" (in other words, an equivalent for ../.. in shell):
7.11. The import statement
When specifying what module to import you do not have to specify the absolute name of the module. When a module or package is contained within another package it is possible to make a relative import within the same top package without having to mention the package name. By using leading dots in the specified module or package after from you can specify how high to traverse up the current package hierarchy without specifying exact names. One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification for relative imports is contained in the Package Relative Imports section.
Is there another way to write it other than doing it in two separate lines like this?
from os.path import isfile, isdir
from os import scandir # or import os.scandir
TL;DR You can't. You got only that method from os.path import <stuff> if you wanna import the functions/objects from inside of os.path.
When you import stuff using just import you can import only modules (module is a term for python file containing python objects). To import the objects inside of a module you use from to traverse upto that module, and then you use import <whateverObject> to import that object from that file (anything and everything is an object in python, as long as it's inside a .py file). The . you use is (generally) to traverse through the directories ('sub' packages?) inside of a package.
How does the interpreter know which directory to include in a package, or how to recognise a given directory as a package? It looks for an __init__.py file inside it. If it finds one, it is a package, and thus you can import it.
import is limited to accessing directories and modules at most, if used alone. When you use from <module_or_directory> import <objects>, the task of accessing directories and/or modules is handed over to the clause after from, and the clause after import takes over the task of looking for python objects inside of the module. You see, these are two distinct things - 1) accessing a file/directory, which comes under file system, and 2) accessing the contents of a file, (specifically, a .py file), which comes under python's domain - neatly separated in the from-import style of importing stuff.
In the case of the os module, os.path is another .pyi file (ntpath.pyi on Windows) that is alias-ed in the os.py file as path. Since it is a module, it goes in the clause after from in from os.path import isfile, isdir. Whereas scandir is a function in os module, hence it goes in the clause after import in from os import scandir.
Based on some answers I try to be more specific.
I want to import the print and the models AND code in my main.py
I know the question gets asked a lot, but still I could not figure out whats wrong with my code!
I have a project directory like this
-project
--__init__py
--main.py
--print.py
--requests
--__init__.py
--models.py
--code.py
i want to import from print.py and * from requests
Therefore I tried to add these lines in main.py
from . import print
#or
import print
#for requests I tried
import os.path
import sys
sys.path.append('./requests')
from requests import *
all of those lines cause the same ImportError attempted relative import with no known parent ,
using Python 39
anyone an idea where the problem is?
I am very confused that this seems not to work, was it possible in older versions?
You should definitely not be doing anything with sys.path. If you are using a correct Python package structure, the import system should handle everything like this.
From the directory structure you described, project would be the name of your package. So when using your package in some external code you would do
import package
or to use a submodule/subpackage
import project.print
import project.requests
and so on.
For modules inside the package you can use relative imports. When you write
i want to import from print.py and * from requests Therefore I tried
it's not clear from where you want to import them, because this is important for relative imports.
For example, in project/main.py to import the print module you could use:
from . import print
But if it's from project/requests/code.py you would use
from .. import print
As an aside, "print" is probably not a good name for a module, since if you import the print module it will shadow the print() built-in function.
Your main file should be outside the 'project'-directory to use that as a package.
Then, from your main file, you can import using from project.print import ....
Within the project-package, relative imports are possible.
I'm cleaning up a project that was refactored into smaller .py files. I noticed that a lot of modules are being imported again and again in various files. Some statements are in files that import another which has the same import statement used by the importing file. For example:
main.py
import alt
print (os.getcwd())
alt.py
import os
The print(os.getcwd()) throws a NameError: name 'os' is not defined. Shouldn't os be part of sys.modules when the import statement is executed in alt.py?
Is it possible to use a module imported by another module that was imported first?
They are available in the following namespace:
import alt
print (alt.os.getcwd())
To answer your immediate question, it is possible but not recommended.
Imports adjust the namespace in which they are made. This means that alt has an attribute os that can be accessed in main as
print(alt.os.getcwd())
This is not the recommended way, however, since it makes it less clear which actual os module you are using. You should do import os directly in main. This will not create a separate module object, so do not worry about cluttering your memory with duplicate modules.
The first time an import is encountered during runtime, it is added to the dictionary sys.modules, keyed by the fully qualified name of the module. Future import statements will look in sys.modules for an existing reference before doing any actual work.
In your case, import alt will create a module referenced by sys.modules['alt'] as well as by the name alt in main. The statement import os in alt will be run next. It will create a module referenced by sys.modules['os'] and alt.os. If you were to add a line import os in main after import alt, it will not create and load another module object. Instead, the name os will be bound to the same object pointed to by sys.modules['os'].
The following three versions of main will all call the same getcwd function:
Direct import (recommended):
import alt
import os
print(os.getcwd())
Use the reference in alt (harder to read/trace):
import alt
print(alt.os.getcwd())
Using sys.modules (really not recommended for production unless you know what you are doing):
import alt # necessary to trigger the actual import
import sys
print(sys.modules['os'].getcwd())
All imports load a full module. This even applies to imports of the form from os import getcwd. The module sys.modules['os'] is still created. The only difference is that the importing namespace will only have access to the name getcwd, not os. In your case, if alt contained from os import getcwd instead of import os, the three access methods would change as follows:
Unchanged.
print(alt.getcwd()) since alt.os no longer exists.
Unchanged.
You are importing os only in the in the submodul level of alt. os is to say so only available by access through alt.os. A way around this would be to import all from alt as from alt import *, but this is not what you should do...
As a general rule of thumb, you should re-import your directly called-to modules on the top level of the module that you currently process.
thus at main.py:
import os
and everything is fine
You write it this way
__author__ = 'kerberos'
__date__ = '2017/10/25 20:48 '
import alt
print(alt.os.getcwd())
This is the result:
C:\Users\Administrator\Desktop\11
I have a directory I add to sys.path to import custom modules. What is the correct/best way to use import, from import and sys.path together? What I mean is if it acceptable to use sys.path.append in between the "imports".
For example:
#!C:/Python27
import sys
sys.path.append('C:\\Users\\user\\myPythonModules')
import writedata as wd
import os
import csv
from collections import defaultdict
Edit:
I should have mentioned that writedata would be a custom module that I want to import as wd. The module writedata is located in C:\\Users\\user\\myPythonModules
Yes, it is. There is no syntax or semantic rule in the language that prevents that.
I am not aware of any "style" rule that you may be breaking, but in any case, another option is providing PYTHONPATH to the python interpreter.