You are on page 1of 18

Review

We've seen that a module is a file that can contain classes as well as its own
variables.
We've seen that you need to import it to access the code, and then use the
module name to refer to it.
import module1
a = module1.ClassName()
Packages
modules: usually single files to do some set of jobs
packages: modules with a namespace, that is, a unique way of referring
to them
libraries: a generic name for a collection of code you can use to get
specific types of job done.
Packages
The Standard Python Library comes with a number of other packages
which are not imported automatically.

We need to import them to use them.


Import
import agentframework
point_1 = agentframework.Agent()
This is a very explicit style. There is little ambiguity about which Agent we are
after (if other imported modules have Agent classes).
This is safest as you have to be explicit about the module. Provided there
aren't two modules with the same name and class, you are fine.

If you're sure there are no other Agent, you can:


from agentframework import Agent
point_1 = Agent()
This just imports this one class.
NB
You will often see imports of everything in a module:
from agentframework import *
This is easy, because it saves you having to import multiple classes, but it is
dangerous: you have no idea what other classes are in there that might
replace classes you have imported elsewhere.
In other languages, with, frankly better, documentation and file structures,
it is easy to find out which classes are in libraries, so you see this a lot.
In Python, it is strongly recommended you don't do this. If you get code
from elsewhere, change these to explicit imports.
As
If the module name is very long (it shouldn't be), you can do this:
import agentbasedmodellingframework as abm
agent_1 = abm.Agent()

If the classname is very long, you can:


from abm import AgentsRepresentingPeople as Ag
agent_1 = Ag()

Some people like this, but it does make the code harder to understand.
When importing, Python will import parent packages (but not other
subpackages)

If hasn’t been used before, will search import path, which is usually
(but not exclusively) the system path.

If you're importing a package, don't have files with the same name (i.e.
package_name.py) in the directory you're in, or they'll be imported
rather than the package (even if you're inside them).
Interpreter
To reload a module:
import importlib
importlib.reload(modulename)

In Spyder, just re-run the module file. Remember to do this if you


update it.
Modules and Packages
Modules are single files that can contain multiple classes, variables, and
functions.

The main difference when thinking of module and scripts is that the
former is generally imported, and the latter generally runs directly.

Packages are collections of modules structured using a directory tree.


Running module code
Although we've concentrated on classes, you can import and run
module-level functions, and access variables.

import module1
print(module1.module_variable)

module1.module_function()
a = module1.ClassName()
Indeed, you have to be slightly careful when Importing modules
importing modules. Modules and the classes in
them will run to a degree on import.

# module Modules run incase


print ("module loading") # Runs there's anything that
needs setting up
def m1(): (variables etc.) prior to
print ("method loading") functions or classes.

class cls:
print ("class loading") # Runs
def m2():
print("instance method loading")
Modules that run
If you're going to use this to run code, note that in general, code accessing a class or
method has to be after if is defined:
c = A()
c.b()
class A:
def b (__self__) :
print ("hello world")

Doesn’t work, but:


class A:
def b (__self__) :
print ("hello world")
c = A()
c.b()
Does
Modules that run
This doesn't count for imported code. This works fine because the files has been scanned down to
c= A() before it runs, so all the methods are recognised.

class A:

def __init__ (self):


self.b()

def b (self) :
print ("hello world")

c = A()
Modules that run
However, generally having large chunks of unnecessary code running is
bad.
Setting up variables is usually ok, as assignment generally doesn't cause
issues.
Under the philosophy of encapsulation, however, we don't really want
code slooping around outside of methods/functions. The core
encapsulation level for Python are the function and objects (with
self; not the class).
It is therefore generally worth minimising this code.
Running a module
The best option is to have a 'double headed' file, that runs as a script with
isolated code, but can also run as a module. As scripts run with a global
__name__ variable in the runtime set to "__main__", the following code in a
module will allow it to run either way without contamination.

if __name__ == "__main__":
# Imports needed for running.
function_name()
Structure that constructs a dot delimited
namespace based around a directory Packages
structure.

/abm The __init__.py can be empty. They allow


__init__.py Python to recognise that the subdirectories are
sub-packages. You can now:
/general import abm.general.agentframework.Agent
__init__.py etc.
agentframework.py The base __init__.py can also include, e.g.
/models __all__ = ["models", "general"]
__init__.py Which means that this will work:
from abm import *
model.py If you want it to.
Running a package

Packages can be run by placing the startup code in a file called


__main__.py
This could, for example use command line args to determine which model to
run.

This will run if the package is run in this form:


python -m packagename
Relatively trivial to include a bat or sh file to run this.
Package Advantages

Structured approach, rather than having everything in one file.

Allows files to import each other without being limited to same directory.

Can set up the package to work together as an application.

The more detailed the namespace (e.g. including unique identifiers) the less
likely your identifiers (classnames; function names; variables) are to clash with
someone else's.

You might also like