Fore­words

A while back I decided to try and learn Python for the hell of it as it seems like an inter­est­ing lan­guage and has some of the most con­cise and user-friendly syn­tax. Hav­ing spent some time going through a num­ber of dif­fer­ent learn­ing sources and mate­ri­als (like the offi­cial site python.org which has a very help­ful tuto­r­ial sec­tion) I have put together a set of notes I made as I was learn­ing and hope­fully they can be use­ful to you as a quick list of how-to code snippets.

All the code snap­shots I’m show­ing here are taken from the IDLE Python shell.

Classes

Some notable dif­fer­ences from the class mech­a­nism in C#:

  • The class inher­i­tance mech­a­nism allows mul­ti­ple base classes
  • Classes are cre­ated at run­time and can be mod­i­fied fur­ther after creation
  • All class mem­bers are pub­lic by default
  • All class mem­bers are virtual
  • Classes them­selves are objects

Like many other lan­guages, most built-in oper­a­tors with spe­cial syn­tax (arith­metic oper­a­tors, sub­script­ing etc.) can be rede­fined for class instances.

 

Sim­ple class definition:

clip_image001

 

To instan­ti­ate a new class:

clip_image002

 

To define a con­struc­tor which takes in some parameters:

clip_image003

to instan­ti­ate this class:

clip_image004

 

When a class defines an __init__() method, class instan­ti­a­tion auto­mat­i­cally invokes this method for the newly-created class instance.

 

To access its attributes:

clip_image005

 

To access its docstring:

clip_image006

 

There are only two kinds of valid attribute names, data attrib­utes and meth­ods.

 

Data attrib­utes don’t need to be declared, they sim­ply spring into exis­tence when they are first assigned to. For instance, for the Per­son class defined above, we can add a new data attribute to an exist­ing instance:

clip_image007

note that the new data attribute belongs to the instance ref­er­enced by x, and doesn’t exist on any other instance of the Per­son class (think Javascript)

 

You can delete the data attribute after you’re done with it:

clip_image008

 

Data attrib­utes can be over­ride by users of an object, so to avoid acci­den­tal name con­flicts it’s best prac­tice to use some kind of con­ven­tion that min­i­mize the chance of con­flicts. E.g. cap­i­tal­iz­ing method names, pre­fix­ing data attribute names with a small unique string, or using verbs for meth­ods and nouns for data attributes.

 

It’s impor­tant to note that noth­ing in Python makes it pos­si­ble to enforce data hid­ing, it’s all based on convention.

 

NOTES: Dif­fer­ence between a func­tion and a method is that a method is a func­tion bound to a class.

 

To define a method on the class:

clip_image009

 

To call the method:

clip_image010

You may have noticed that in the method def­i­n­i­tion say_greeting takes a sin­gle para­me­ter self but it was called with none. This is a spe­cial rule which applies to meth­ods where the object is passed as the first argu­ment. The con­ven­tion is to call the first argu­ment of a method self.

 

It’s not nec­es­sary that the func­tion def­i­n­i­tion is tex­tu­ally enclosed in the class definition:

clip_image011

and you can still use it like before:

clip_image012

 

To call other meth­ods inside the class:

clip_image013

 

To find the class of an instance:

clip_image014

 

To cre­ated a derived class:

clip_image015

because we haven’t defined any new attrib­utes, every­thing will be inher­ited from Per­son includ­ing the __init__ method:

clip_image016

 

If a requested attribute is not found in the class, the search pro­ceeds to look in the base class and if still not found it pro­ceeds to look in the base class of that class, and so on.

You can also extend a base method instead of replac­ing it, to call a base class method:

clip_image017

 

Use isin­stance() func­tion to check if an object is an instance of a class or some class derived from it:

clip_image018

 

Use issub­class() func­tion to check if a class derives from another:

clip_image019

 

Every class keeps these built-in attributes:

  • __dict__ : Dic­tio­nary con­tain­ing the class’s namespace.
  • __doc__ : Class doc­u­men­ta­tion string, or None if undefined.
  • __name__: Class name.
  • __module__: Mod­ule name in which the class is defined. This attribute is “__main__” in inter­ac­tive mode.
  • __bases__ : A pos­si­bly empty tuple con­tain­ing the base classes, in the order of their occur­rence in the base class list.

clip_image020

 

Python’s garbage col­lec­tor runs dur­ing pro­gram exe­cu­tion and is trig­gered when an object’s ref­er­ence count reaches zero.

You can imple­ment a destruc­tor, __del__() method, that is invoked when the instance is about to be destroyed.

 

Here’s a list of some of the meth­ods you can over­ride in your own class:

clip_image021

 

Python sup­ports mul­ti­ple inher­i­tance:

clip_image022

 

Whilst you can’t hide an object’s attrib­utes you can still make them not directly vis­i­ble to out­siders by adding a dou­ble under­score prefix:

clip_image023

What’s hap­pened is that Python changed the name of these attrib­utes to include the class name:

clip_image024

So you can still access them like this:

clip_image025

This is called name man­gling it is mostly designed to avoid acci­den­tal name con­flicts as opposed to pro­vide data hiding.

 

Most con­tainer objects can be looped over using a for state­ment, under­neath, the for state­ment calls iter() on the con­tainer object and gets back an object that defines the method next(). When there are no more ele­ments, next() raises a Sto­pIt­er­a­tion excep­tion which tells the for loop to terminate.

 

Here’s how you might cre­ate a cus­tom iter­a­tor which loops through a con­tainer object in reverse:

clip_image026

clip_image027

 

Mod­ules

A mod­ule allows you to log­i­cally orga­nize your Python code, a mod­ule is a file con­tain­ing Python def­i­n­i­tions and statements.

The file name is the mod­ule name with the .py extension.

Within a mod­ule, the mod­ule name is avail­able as the value of the global vari­able __name__.

You can import an entire mod­ule in your code, or just spe­cific sub­set of the func­tions defined in the mod­ule. For exam­ple, to import the def­i­n­i­tions in a file called ‘fib.py’ in the cur­rent directory:

clip_image001[4]

 

A mod­ule can con­tain exe­cutable state­ments as well as func­tions, these state­ments are intended to ini­tial­ize the mod­ule and are exe­cuted only the first time the mod­ule is imported somewhere.

 

Each mod­ule has its own pri­vate sym­bol table which is used as the global sym­bol table by all the func­tions defined in the mod­ule. This way, you won’t have to worry about acci­den­tal clashes with global vari­able names. How­ever, if required, you could still access a mod­ules global vari­ables with modulename.itemname.

 

You can import a sub­set of the items from a mod­ule using a vari­ant of the import state­ment. To import spe­cific func­tions or variables:

clip_image002[4]

 

You can import all names from a mod­ule except those begin­ning with an underscore:

clip_image003[4]

 

You can use the python exe­cutable to run a python script:

clip_image004[4]

When you do this, the __name__ global vari­able of the script is changed to __main__, and by adding the fol­low­ing lines to your script you can make the file usable as a script as well as an importable module:

clip_image005[4]

clip_image006[9]

 

When you ask to import a mod­ule called fib, Python first looks for a file named fib.py in the cur­rent direc­tory, if not found it then looks in the list of direc­to­ries spec­i­fied by the envi­ron­ment vari­able PYTHONPATH.

You mustn’t name your script the same as a stan­dard mod­ule, or Python will attempt to load the script as a mod­ule when that mod­ule is imported..

 

To improve the start-up time of short pro­grams that use a lot of stan­dard mod­ules, python gen­er­ates a com­piled ver­sion of the mod­ule. For instance, for the mod­ule fib, the fib.pyc con­tains a byte-compiled ver­sion of the fib.py file. The mod­i­fi­ca­tion time of the ver­sion of fib.py used to cre­ate fib.pyc is recorded in fib.pyc file and is used to deter­mine whether fib.pyc is up to date and there­fore if it could be used.

How­ever, it’s worth not­ing that a pro­gram doesn’t run faster when it’s read from a .pyc file instead of .py file, it’s only loaded faster.

When a script is run from the com­mand line the byte-code for the script is never writ­ten to a .pyc file. You can improve the load time for these scripts by mov­ing most of its code to a mod­ule and hav­ing a small boot­strap script that imports that module.

It’s pos­si­ble to have a .pyc file with­out the cor­re­spond­ing .py file, this can be used to dis­trib­ute a library of Python code in a form that is mod­er­ately hard to reverse engineer.

 

You can use the com­pileall mod­ule to cre­ate .pyc files for ALL .py files in a directory:

clip_image007[4]

sys.py is one of the stan­dard mod­ules, and use sys.path you can see all the paths which Python will look when it’s try­ing to find a mod­ule to import:

clip_image008[4]

Of course, you can add to that path:

clip_image009[8]

But remem­ber, this change is only valid in the cur­rent ses­sion, when you restart the inter­preter this new path will be lost.

 

To find out what names are defined in a mod­ule, use the built-in dir() function:

clip_image010[4]

 

With­out argu­ment, dir() lists all the names you have defined currently:

clip_image011[4]

Another handy thing you can do with the dir() func­tion is to use to list all the built-in functions:

clip_image012[4]

 

You can put a col­lec­tion of related mod­ules in a pack­age. Here’s a pos­si­ble struc­ture for a sound pack­age in terms of file hierarchies:

clip_image013[4]

The __init__.py files are required to make Python treat the direc­to­ries as con­tain­ing pack­ages. It can be an empty file, but it can also exe­cute ini­tial­iza­tion code for the package.

 

To import an indi­vid­ual mod­ule of the package:

clip_image014[4]

But it must be ref­er­enced with its full name:

clip_image015[8]

 

Alter­na­tively you could also:

clip_image016[8]

The ben­e­fit of this approach is so that you don’t need the full name to ref­er­ence it:

clip_image017[4]

 

Or, if all you want is the echofil­ter func­tion, you could also:

clip_image018[4]

And to ref­er­ence it:

clip_image019[4]

 

When the users write from sound.effects import * the import state­ment uses the fol­low­ing convention:

  • If a package’s __init__.py code defines a list named __all__, it is taken to be the list of mod­ules names that should be imported when from pack­age import * is encountered:

clip_image020[4]

  • If __all__ is not defined, from sound.effects import * only ensures that the pack­age sound.effects is imported and run any ini­tial­iza­tion code in __init__.py.

 

The rec­om­mended approach is to import spe­cific mod­ules using from Pack­age import module.

 

You can also rel­a­tive paths from the cur­rent mod­ule, so from the sur­round mod­ule you might:

clip_image021[4]

Where . refers to the cur­rent pack­age, .. refers to the par­ent pack­age, ..fil­ters refers to the fil­ters pack­age at the same level as the par­ent package

Because the name of the main mod­ule is always “__main__”, there­fore mod­ules intended for use as the main mod­ule of a Python appli­ca­tion should always use absolute imports.

Share

Leave a Reply