How to Write a Python Module/Package

How to write a Python module/package?

A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py

create hello.py then write the following function as its content:

def helloworld():
print "hello"

Then you can import hello:

>>> import hello
>>> hello.helloworld()
'hello'
>>>

To group many .py files put them in a folder. Any folder with an __init__.py is considered a module by python and you can call them a package

|-HelloModule
|_ __init__.py
|_ hellomodule.py

You can go about with the import statement on your module the usual way.

For more information, see 6.4. Packages.

How to write a Python package/module?

Well, a solution is to create a directory to add your modules and add this directory to the Python pat. For example, you can create a directory at, let us say, C:\mypymodules and put a cls.py file there with your function.

Now, let us add this directory to the Python path. Follow these instructions, just inserting C:\mypymodules in place of the directories mentioned there. Now, open a new command line window and try to import the module.

Another solution is to use distutils*. Instead of creating your own modules directory, in the same directory of your cls.py file create a file named setup.py with the following content:

from distutils.core import setup
setup(name='cls', py_modules=['cls'])

Then, just execute it:

> python setup.py install

This may install your module in the default Python library directories. Actually, this is the way (or, better yet, one of the ways) to pack, manage or python packages.

(I am not really using Windows, so some details may be broken. Nonetheless, I believe the general concepts are the same.)

* Some may argue about using setuptools but I think it is really overkill for your case. Anyway, if you want to learn more, see this question.

How to package a python module that imports another module within that package

Please try to import it as below ...

from foo.helper_class import HelperClass

What is __init__.py for?

It used to be a required part of a package (old, pre-3.3 "regular package", not newer 3.3+ "namespace package").

Here's the documentation.

Python defines two types of packages, regular packages and namespace packages. Regular packages are traditional packages as they existed in Python 3.2 and earlier. A regular package is typically implemented as a directory containing an __init__.py file. When a regular package is imported, this __init__.py file is implicitly executed, and the objects it defines are bound to names in the package’s namespace. The __init__.py file can contain the same Python code that any other module can contain, and Python will add some additional attributes to the module when it is imported.

But just click the link, it contains an example, more information, and an explanation of namespace packages, the kind of packages without __init__.py.

How to limit a Python module to expose specific parts

If this is your module mymodule.py:

def expose_this():
print('yes please')

def but_not_this():
print('definitely not')

Importing it directly like this:

import mymodule

Gives a user access to mymodule.expose_this() and mymodule.but_not_this(), there's no way to change that, although you could call but_not_this something like _but_not_this instead and many editors would at least warn a user that they are not supposed to access that.

However, the right way to do it would be to create a package. Put your module in a separate folder (called mymodule), and add an __init__.py with this:

from .mymodule import expose_this

Now, if someone imports your package using the same import statement as before, they only have access to mymodule.expose_this()

import mymodule

mymodule.expose_this() # this works
mymodule.but_not_this() # this causes an error

There's a lot more to say about creating packages and how to add content, but there's good documentation and tutorials for that out there.

Note: if someone knows the internal structure of your module, they can still access but_not_this() with this:

import mymodule

mymodule.mymodule.but_not_this()

But they'd have to really want to - making it impossible is hard and there's really no point, since someone will be able to get at your code anyway, if they need to. But if you want to make the intent clear, you could rename mymodule.py to _mymodule.py and prefix the functions you don't want exposed with a _ as well - this helps editors to reinforce your intentions with the user.

Python Import system, importing function from a module that imports the same function from another package

This is perfectly fine. The from x import name statement merely imports name from x – it does not care where name was initially defined.

In fact, the standard library itself frequently re-exports names from internal or C modules.

# collections/abc.py
from _collections_abc import *
from _collections_abc import __all__
from _collections_abc import _CallableGenericAlias

Re-exporting names can help make the public appearance of a package simpler to use, while giving complete freedom to how the implementation is structured.

However, one should be careful when re-exporting names across packages. Just because a package exposes a name today does not mean that a future version does so as well. When the intermediate package is not under your control, avoid making assumptions and prefer importing from the official source.

# bad: import undocumented attribute
from subprocess import os
# good: import with official name
import os

The notion of "where" an object was defined does not generally make sense. For example, consider defining a module for literal constants:

# constants.py
MIDNIGHT = 0
NOON = 12

There is a single value for every 0 and 12 throughout the entire application. The statement from constants import MIDNIGHT, NOON has no way of checking where the objects were defined initially.



Related Topics



Leave a reply



Submit