Week 5-7 - State University of Zanzibar

Download Report

Transcript Week 5-7 - State University of Zanzibar

Week 5-7
PYTHON CLASS
Defining Classes
• Class: A user-defined prototype for an object
that defines a set of attributes that
characterize any object of the class.
• The attributes are data members (class
variables and instance variables) and
methods, accessed via dot notation.
Classes
• Class variable: A variable that is shared by all
instances of a class.
• Class variables are defined within a class but
outside any of the class's methods.
• Class variables aren't used as frequently as
instance variables are.
Classes
• Data member: A class variable or instance
variable that holds data associated with a
class and its objects.
• Function overloading: The assignment of
more than one behavior to a particular
function. The operation performed varies by
the types of objects (arguments) involved.
Classes
• Instance variable: A variable that is defined
inside a method and belongs only to the
current instance of a class.
• Instance: An individual object of a certain
class.
• An object obj that belongs to a class Circle, for
example, is an instance of the class Circle.
Classes
• Instantiation : The creation of an instance of a
class.
• Method : A special kind of function that is
defined in a class definition.
• Object : A unique instance of a data structure
that's defined by its class.
• An object comprises both data members (class
variables and instance variables) and
methods.
Classes
• Operator overloading: The assignment of
more than one function to a particular
operator.
Python Scopes and Namespaces
• A namespace is a mapping from names to
objects.
• Most namespaces are currently implemented
as Python dictionaries, but that’s normally not
noticeable in any way (except for
performance), and it may change in the
future.
Examples of Namespaces
• Examples of namespaces are: the set of builtin names (containing functions such as:
• abs()
• built-in exception names)
• the global names in a module
• the local names in a function invocation.
• In a sense the set of attributes of an object
also form a namespace.
Attribute
• By the way, I use the word attribute for any
name following a dot.
• for example, in the expression
• z.real
• real is an attribute of the object z.
cont
• Namespaces are created at different moments
and have different lifetimes.
• The namespace containing the built-in names
is created when the Python interpreter starts
up, and is never deleted.
• The global namespace for a module is created
when the module definition is read in;
normally, module namespaces also last until
the interpreter quits.
cont
• The local namespace for a function is created
when the function is called, and deleted when
the function returns or raises an exception
that is not handled within the function.
Scope
• A scope is a textual region of a Python
program where a namespace is directly
accessible. “Directly accessible” here means
that an unqualified reference to a name
attempts to find the name in the namespace.
Scope
• Although scopes are determined statically,
they are used dynamically.
• At any time during execution, there are at
least three nested scopes whose namespaces
are directly accessible:
cont
• the innermost scope, which is searched first,
contains the local names
• the scopes of any enclosing functions, which are
searched starting with the nearest enclosing
scope, contains non-local, but also non-global
names
• the next-to-last scope contains the current
module’s global names
• the outermost scope (searched last) is the
namespace containing built-in names
cont
• If a name is declared global, then all
references and assignments go directly to the
middle scope containing the module’s global
names.
• To rebind variables found outside of the
innermost scope, the nonlocal statement can
be used; if not declared nonlocal, those
variable are read-only
Scopes and Namespaces Example
• This is an example demonstrating how to
reference the different scopes and
namespaces, and how global and nonlocal
affect variable binding:
Example
def scope_test():
def do_local():
spam = "localspam"
def do_nonlocal():
nonlocal spam
spam = "nonlocalspam"
def do_global():
global spam
spam = "globalspam"
spam = "testspam"
do_local()
print("Afterlocalassignment:", spam)
do_nonlocal()
print("Afternonlocalassignment:", spam)
do_global()
print("Afterglobalassignment:", spam)
scope_test()
print("Inglobalscope:", spam)
output
•
•
•
•
•
The output of the example code is:
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
Note
• Note how the local assignment (which is
default) didn’t change scope_test‘s binding of
spam. The nonlocal assignment changed
scope_test‘s binding of spam, and the global
assignment changed the module-level binding.
• You can also see that there was no previous
binding for spam before the global
assignment.
A First Look at Classes
• Classes introduce a little bit of new syntax, three
new object types, and some new semantics.
• Class Definition Syntax
class ClassName:
<statement-1>
.
.
.
<statement-N>
Class Definition
• Class definitions, like function definitions (def
statements) must be executed before they
have any effect.
• You could conceivably place a class definition
in a branch of an if statement, or inside a
function.
Class Definition
• In practice, the statements inside a class
definition will usually be function definitions,
but other statements are allowed, and
sometimes useful.
• The function definitions inside a class
normally have a peculiar form of argument
list, dictated by the calling conventions for
methods.
cont
• When a class definition is entered, a new
namespace is created, and used as the local
scope — thus, all assignments to local
variables go into this new namespace. In
particular, function definitions bind the name
of the new function here.
cont
• When a class definition is left normally (via the
end), a class object is created.
• This is basically a wrapper around the contents of
the namespace created by the class definition;
we’ll learn more about class objects in the next
section.
• The original local scope (the one in effect just
before the class definition was entered) is
reinstated, and the class object is bound here to
the class name given in the class definition
header (ClassName in the example).
cont
• Class objects support two kinds of operations:
attribute references and instantiation.
• Attribute references use the standard syntax
used for all attribute references in Python:
obj.name.
• Valid attribute names are all the names that
were in the class’s namespace when the class
object was created.
• So, if the class definition looked like this:
cont
• class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return ’helloworld’
cont
• then MyClass.i and MyClass.f are valid
attribute references, returning an integer and
a function object, respectively.
• Class attributes can also be assigned to, so you
can change the value of MyClass.i by assignment. __doc__ is also a valid attribute,
returning the docstring belonging to the class:
"A simple example class".
cont
• Class instantiation uses function notation. Just
pretend that the class object is a
parameterless function that returns a new
instance of the class.
• For example (assuming the above class):
• x = MyClass()
• creates a new instance of the class and assigns
this object to the local variable x.
cont
• The instantiation operation (“calling” a class
object) creates an empty object. Many classes
like to create objects with instances
customized to a specific initial state.
• Therefore a class may define a special method
named __init__(), like this:
• def __init__(self):
self.data = []
cont
• When a class defines an __init__() method, class
instantiation automatically invokes __init__() for
the newly-created class instance.
• So in this example, a new, initialized instance can
be obtained by:
• x = MyClass()
• Of course, the __init__() method may have
arguments for greater flexibility.
• In that case, arguments given to the class
instantiation operator are passed on to __init__().
Self Keyword and Constructor
• Methods are added to the class with def.
• The first argument to a method is the class instance.
• By convention it is spelled "self".
• self is a reference to the instance. Think of it (i
n part) as a reference to the container for the
data or state for the object.
Self
• In many object-oriented programming languages, the instance is hidden in the method definitions.
• These languages typically explain this by sayin
g something like "The instance is passed as an
implicit first argument to the method."
Self
• In Python, the instance is visible and explicit in
method definitions.
• You must explicitly declare the instance as the
first parameter of each (instance) method.
• This first parameter is (almost) always spelled
"self".
Self
• The self variable must be explicitly listed as th
e first argument to a method.
• You could spell it differently from "self", but d
on't do so.
• Instance variables are referred to with "self.XX
X".
Constructor
• The constructor for a class is a method named
__init__.
• Constructor is initialization method that
Python calls when you create a new instance
of this class.
For example
• >>> class Complex:
…
def __init__(self, realpart, imagpart):
...
self.r = realpart
...
self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Instance Objects
• The only operations understood by instance
objects are attribute references.
• There are two kinds of valid attribute names,
data attributes and methods.
• Data attributes need not be declared; like
local variables, they spring into existence
when they are first assigned to.
Instance Objects
• For example, if x is the instance of MyClass
created above, the following piece of code will
print the value 16, without leaving a trace:
• x.counter = 1
while x.counter < 10:
x.counter = x.counter * 2
print(x.counter)
del x.counter
cont
• The other kind of instance attribute reference
is a method. A method is a function that
“belongs to” an object.
• In Python, the term method is not unique to
class instances: other object types can have
methods as well.
cont
• Valid method names of an instance object
depend on its class.
• By definition, all attributes of a class that are
function objects define corresponding methods
of its instances.
• So in our example, x.f is a valid method reference,
since MyClass.f is a function, but x.i is not, since
MyClass.i is not.
• But x.f is not the same thing as MyClass.f — it is a
method object, not a function object.
Method Objects
• Usually, a method is called right after it is bound:
• x.f()
• In the MyClass example, this will return the string ’hello
world’.
• However, it is not necessary to call a method right away: x.f
is a method object, and can be stored away and called at a
later time.
• For example:
• xf = x.f
• while True:
print(xf())
• will continue to print hello world until the end of time.
cont
• What exactly happens when a method is called?
• You may have noticed that x.f() was called
without an argument above, even though the
function definition for f() specified an argument.
• What happened to the argument?
• Surely Python raises an exception when a
function that requires an argument is called
without any — even if the argument isn’t actually
used...
cont
• Actually, you may have guessed the answer: the
special thing about methods is that the object is
passed as the first argument of the function. In
our example, the call x.f() is exactly equivalent to
MyClass.f(x).
• In general, calling a method with a list of n
arguments is equivalent to calling the
corresponding function with an argument list that
is created by inserting the method’s object before
the first argument.
Examples
class Basic:
def __init__(self, name):
self.name = name
def show(self):
print('Basic name: %s' % self.name)
def test():
obj1 = Basic('Apricot')
obj1.show()
test()
Running the code
• Running the above example produces the followi
ng:
• Basic name: Apricot
• Notice how in our example an argument to the c
onstructor is saved as an instance variable.
• An instance is created by "calling" the class.
• For example: obj1 = Basic('Apricot').
• In addition to __init__ there are other special me
thod names of the form
cont
• "__XXX__", which are used to customize class
es and their instances.
• These are described at Python Language Refe
rence
Example
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print("Total Employee %d" % Employee.empCount)
def displayEmployee(self):
print("Name : ", self.name, ", Salary: ", self.salary)
Creating instance objects
• To create instances of a class, you call the class
using class name and pass in whatever
arguments its __init__ method accepts.
• "This would create first object of Employee
class"
• emp1 = Employee("Zara", 2000)
• "This would create second object of Employee
class"
• emp2 = Employee("Manni", 5000)
Accessing attributes
• You access the object's attributes using the dot
operator with object. Class variable would be
accessed using class name as follows:
emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)
Putting all together
#!/usr/bin/python
class Employee:
'Common base class for all employees‘
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
cont
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
#"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
#"This would create second object of Employee
#class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
cont
• When the above code is executed, it produces
the following result:
• Name : Zara ,Salary: 2000
• Name : Manni ,Salary: 5000
• Total Employee 2
• You can add, remove or modify attributes of
classes and objects at any time:
cont
• emp1.age = 7 # Add an 'age' attribute.
emp1.age = 8 # Modify 'age' attribute.
del emp1.age # Delete 'age' attribute.
Destructor - Destroying Objects
(Garbage Collection)
• Python deletes unneeded objects (built-in
types or class instances) automatically to free
memory space.
• The process by which Python periodically
reclaims blocks of memory that no longer are
in use is termed garbage collection.
cont
• Python's garbage collector runs during
program execution and is triggered when an
object's reference count reaches zero.
• An object's reference count changes as the
number of aliases that point to it changes.
cont
• An object's reference count increases when
it's assigned a new name or placed in a
container (list, tuple or dictionary).
• The object's reference count decreases when
it's deleted with del, its reference is
reassigned, or its reference goes out of scope.
• When an object's reference count reaches
zero, Python collects it automatically.
cont
•
•
•
•
•
•
•
•
•
•
•
•
a = 40
# Create object <40>
b=a
# Increase ref. count of <40>
c = [b]
# Increase ref. count of <40>
del a
# Decrease ref. count of <40>
b = 100
# Decrease ref. count of <40>
c[0] = -1
# Decrease ref. count of <40>
cont
• You normally won't notice when the garbage
collector destroys an orphaned instance and
reclaims its space.
• But a class can implement the special method
__del__(), called a destructor, that is invoked
when the instance is about to be destroyed.
• This method might be used to clean up any
nonmemory resources used by an instance.
Example
• This __del__() destructor prints the class name of
an instance that is about to be destroyed:
#!/usr/bin/python
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
cont
class_name = self.__class__.__name__
print(class_name, "destroyed“)
pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3)) # prints the ids of the objects
del pt1
del pt2
del pt3
cont
• When the above code is executed, it produces
following result:
• 3083401324 3083401324 3083401324
• Point destroyed
Using Classes in Python
•
•
•
•
Example
# ClassOne.py
Class Calculator(Object):
“Define a class to simulate a simple
calculator”
• def __init__(self):
#start with zero
self.current = 0
Using Classes in Python
• def add(self, amount):
• # add number to current
•
self.current += amount
• def getCurrent(self):
•
return self.current
Using Classes in Python
• To Class Calculator() in the file ClassOne.py do
the following:
• Make sure all your files are in one directory
• Put your code that want to use the Class
Calculator() in another file.
• Write the following in the other file
• from ClassOne import *
• # get all from file ClassOne
Example
•
•
•
•
from ClassOne import *
myBuddy = Calculator()
myBuddy.add(2)
print(myBuddy.getCurrent())
Tip
• Initializing vars: Only constant initializers for
class variables are allowed (n = 1). To initialize
variables with non-constant values, you must
use the constructor. You cannot declare
uninitialized variables.
Function Overloading
• There is no function overloading in Python.
• Unlike Java, a Python function is specified by
its name alone.
• The number, order, names, or types of its
arguments cannot be used to distinguish
between two functions with the same name.
• Two different functions can’t have the same
name, even if they have different numbers of
arguments.
Function Overloading
• Following table lists some generic
functionality that you can override in your
own classes:
Function Overloading
SN
Method, Description & Sample Call
1
__init__ ( self [,args...] )
Constructor (with any optional arguments)
Sample Call : obj = className(args)
2
_del__( self )
Destructor, deletes an object
Sample Call : dell obj
3
__repr__( self )
Evaluatable string representation
Sample Call : repr(obj)
4
__str__( self )
Printable string representation
Sample Call : str(obj)
5
__cmp__ ( self, x )
Object comparison
Sample Call : cmp(obj, x)
Operator Overloading
• Suppose you've created a Vector class to
represent two-dimensional vectors, what
happens when you use the plus operator to
add them? Most likely Python will yell at you.
• You could, however, define the __add__
method in your class to perform vector
addition and then the plus operator would
behave as per expectation:
Example
• #!/usr/bin/python
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
When the above code is executed, it produces the following result:
Vector(7,8)