User Tools

Site Tools


programming:python:packaging

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
programming:python:packaging [2018-07-24 05:37] – old revision restored (2018-07-24 04:44) zlgprogramming:python:packaging [2023-11-06 20:36] (current) – add notice about Python community's kerfuffle about packaging zlg
Line 1: Line 1:
 ====== Packaging ====== ====== Packaging ======
  
-In Python, individual source files are referred to as **modules**. They represent a single collection of code, and can be ''import''ed. **Packages** are directories containing an ''%%__init__.py%%'' file and other modules. They are comparable to namespaces, and can also be ''import''ed.+FIXME :!: The Python community has some PEPs and a lot of debate over what the 'correct' way to package Python programs is. As of November 2023 I'm not totally sure what the way forward is meant to be for PyPI projects, or if the below information is still true about Python's module handling. Consume appropriate amounts of salt where sus. :!: 
 + 
 +In Python, individual source files are referred to as **modules**. They represent a single collection of code, and can be ''import''ed. **Packages** are directories containing an ''%%__init__.py%%'' file and other modules. They are comparable to namespaces, and can also be ''import''ed. A package with an empty ''%%__init__.py%%'' file is completely fine; it just won't import any modules when imported.
  
 Here's an example of a //package// containing //modules//: Here's an example of a //package// containing //modules//:
Line 14: Line 16:
 </code> </code>
  
-There are multiple ways to interact with a package, which are covered below. In every case, it's assumed that the Python interpreter is in the directory //above// ''my_package/''.+There are multiple ways to interact with a package, which are covered below. In every case, it's assumed that the Python interpreter is in the directory //above// ''my_package/'', or ''my_package/'' is somewhere in Python's path variable. See [[https://docs.python.org/3/library/sys.html#sys.path|Python's documentation on sys.path]] for information on that.
  
 ===== Simple Importing ===== ===== Simple Importing =====
Line 32: Line 34:
 The ''.'' here means "the current package". If you have sub-packages, you can address them with a dot preceding its name, like ''.my_subpackage''. The ''.'' here means "the current package". If you have sub-packages, you can address them with a dot preceding its name, like ''.my_subpackage''.
  
-If every module is needed in your package, you can leave ''%%__init__%%.py'' as an empty file and Python will figure it out for you. 
- 
-The same effect can be achieved using the ''%%__all__%%'' variable: 
- 
-<code python __init__.py> 
-# Overload the __all__ variable to hook into existing Python logic 
-__all__ = ["model", "router"] 
-</code> 
 ===== Single Module Importing ===== ===== Single Module Importing =====
  
Line 60: Line 54:
 </code> </code>
  
-In the above example, ''do_route'' will become available in the current environment, imported from the ''router'' module inside the ''my_package'' package. If you end up with name collisionsyou can rename the import with the ''as'' keyword:+In the above example, ''do_route'' will become available in the current environment, imported from the ''router'' module inside the ''my_package'' package. 
 + 
 +If you find yourself with strange ''NameError''s''AttributeError''s, or ''ValueError''s, it may point to a name collision. You can rename your imports with the ''as'' keyword:
  
 <code python> <code python>
Line 67: Line 63:
 </code> </code>
  
 +This is often caused by importing two modules with the same member name. If you import two things with the same member name, the latter name will take precedence:
 +
 +<code python>
 +# Same name, different structures
 +from os import path
 +print(type(path))
 +# <class 'module'>
 +from sys import path
 +print(type(path))
 +# <class 'list'>
 +</code>
 +
 +For this reason, it's generally better to leave imports alone and go one level deeper only as needed. So if you wanted to use ''path'' from both ''os'' and ''sys'', just import them on their own, so you're using ''os.path'' and ''sys.path''. It's more verbose, but also more precise and less likely to break.
 ====== References ====== ====== References ======
  
programming/python/packaging.1532410636.txt.gz · Last modified: 2018-07-24 05:37 by zlg