Python Import, Paths, Directories, and Modules

Let me begin by doing extensive research over the past week and not yet found real answers to these questions - just some fuzzy answers that don't really explain what is happening. If this is just the reason, I missed what I was looking for, I'm sorry - please just point me in the right direction.

My directory structure:

TestProject/ runtest* testpackage/ __init__.py testmod.py testmod2.py testsubs/ testsubmod.py 

A few notes:

  • I am using python2.7 on Ubuntu
  • I am testing bpython
  • I am running bpython from specific directories to check the import method.
  • I am trying to follow best practices.
  • This package is not installed, it is located in an arbitrary dev directory
  • This directory is not in pythonpath
  • I have one init .py in the package directory
  • There are no files in the subdirectories.
init .py. Init .py file is empty testpackage / testmod.py contains TestModClass testpackage / testsubs / testsubmod.py contains TestSubModClass

Things I observed:

  • When I start bpython from TestProject / import testpackage works
    • This does not import testpackage.testmod
    • I cannot access testpackage.testmod at all
  • When I run bpython from TestProject / import testpackage.testmod , it does not execute
  • When I run bpython from TestProject / from testpackage import testmod works
  • I can add code to init .py to explicitly import testmod.py but not testubs / testmod.py
    • I don't think this is the right way to do this, what if the user does not want to import this module?
  • from testmod.py I can import testmod2 but not testpackage.testmod2
    • It would be nice to make it possible for me to call my own modules with overlapping names using STL or twisted (e.g. testpackage.logging) without causing errors (it sucks to name my own modules like bloglogging and not just mypackage .logging)

And questions:

  • Is python different in importing packages and modules existing in pythonpath than when trying to import from the current directory?
  • Why doesn't import testpackage, give me access to testpackage.testmod? When I import os, I can access os.path (etc.).
  • With the package, should I use a single init .py in the base directory, or should I paste them into subsequent directories?
  • How to import a module that defines a package name? I.E. from testmod.py, I would like to import testpackage.testmod2, not just testmod2.
  • What is the correct way to import submodules from a subdirectory directory?
    • The only solution I see is to add this directory to the pythonpath from init .py, but I don't know if this is correct.

Thanks in advance.

+6
source share
2 answers

First, you will find all the necessary information in section 6 of the Python lesson .


(1) Does python work differently with importing packages and modules existing in pythonpath than when trying to import from the current directory?

No, it is not. In fact, Python always searches for sys.path when importing modules. Modules in the current directory are found only since sys.path contains an entry with an empty string, which means the current directory.


(2) Why import testpackage n't import testpackage give me access to testpackage.testmod ? When I import os , I can access os.path (etc.).

For efficiency, import testpackage only loads testpackage/__init__.py . If you need testpackage.testmod , you must explicitly import it:

 import testpackage # Just imports testpackage, not testpackage.testmod! import testpackage.testmod # Import *both* testpackage and testpackage.testmod! 

If you always want to export testmod , import it into __init__.py , this is what os ( os/__init__.py ) os/__init__.py . Thus, testpackage.testmod always available implicitly if you import testpackage .

Since Python is cross-platform, there really is no way to sequentially and automatically load modules into a directory, because some file systems are not case sensitive (Windows!). Python does not know whether to load os/path.py as os.path or os.path , etc.


(3) With the package, should I use one __init__.py in the base directory, or should I insert them into subsequent directories?

Each subpacket always requires __init__.py . There were discussions on the abolition of this requirement, but it was decided to keep it as it is.


(4) How to import a module that defines a package name? I.E. from testmod.py , I would like to import testpackage.testmod2 , not just testmod2 .

That should work. Just make sure you run the code from the top-level directory. If the current directory is testpackage , testmod does not know that it is in the package.

The preferred way is to use relative imports within the package:

 from . import testmod2 

This prevents name collisions if there is a global module named testmod2 and allows you to easily use the names of known modules inside your package.


(5) What is the correct way to import submodules from a subscription catalog? The only solution I see is to add this directory to the pythonpath from __init__.py , but I don't know if this is correct.

No, do not do this! Never, never put a directory in sys.path when one of its parent directories is already in sys.path ! This can lead to loading modules twice, which is bad!

Usually you should be able to load modules from subpackages using absolute or relative imports:

 import testpackage.testsubs.testsubmod from testpackage.testsubs import testsubmod from .testsubs import testsubmod 

Just create __init__.py inside testsubs/ !

+8
source
  • Not. The current directory is only added to PYTHONPATH.
  • First, you need __init__.py. Secondly, os.path happens because os imports os.path.
  • You need __init__.py in each directory, also in the directory containing the testpackage directory.
  • In the __init__.py package, import the modules you want to provide.
  • from the import submodule sub1.sub2
    • No, if the topmost directory is on PYTHONPATH, and this and its subdirectories have their own __init__.py, that's all you need to import from any of the subdirectories.
0
source

Source: https://habr.com/ru/post/895686/


All Articles