KEMBAR78
Python 3 | PDF | Class (Computer Programming) | Method (Computer Programming)
0% found this document useful (0 votes)
8 views58 pages

Python 3

Uploaded by

yayavoj884
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views58 pages

Python 3

Uploaded by

yayavoj884
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

Python 3

Some material adapted


from Upenn cis391
slides and other sources
Importing and
Modules
Importing and Modules
∙ Use classes & functions defined in another file
∙ A Python module is a file with the same name
(plus the .py extension)
∙ Like Java import, C++ include
∙ Three formats of the command:
import somefile
from somefile import *
from somefile import className
∙ The difference? What gets imported from the
file and what name refers to it after importing
import …
import somefile

∙ Everything in somefile.py gets imported.


∙ To refer to something in the file, append the
text “somefile.” to the front of its name:

somefile.className.method(“abc”)
somefile.myFunction(34)
from … import *
from somefile import *
∙ Everything in somefile.py gets imported
∙ To refer to anything in the module, just use its
name. Everything in the module is now in the
current namespace.
∙ Take care! Using this import command can
easily overwrite the definition of an existing
function or variable!
className.method(“abc”)
myFunction(34)
from … import …
from somefile import className
∙ Only the item className in somefile.py gets
imported.
∙ After importing className, you can just use
it without a module prefix. It’s brought into the
current namespace.
∙ Take care! Overwrites the definition of this
name if already defined in the current
namespace!
className.method(“abc”) imported
myFunction(34) Not imported
Directories for module files

∙ Where does Python look for module files?


∙ The list of directories where Python will look
for the files to be imported is sys.path
∙ This is just a variable named ‘path’ stored
inside the ‘sys’ module
>>> import sys
>>> sys.path
['',
'/Library/Frameworks/Python.framework/Versions/2.5/lib/pyth
on2.5/site-packages/setuptools-0.6c5-py2.5.egg’, …]
∙ To add a directory of your own to this list,
append it to this list
sys.path.append(‘/my/new/path’)
Object Oriented Programming
in Python:
Defining Classes
It’s all objects…
∙ Everything in Python is really an object.
• We’ve seen hints of this already…
“hello”.upper()
list3.append(‘a’)
dict2.keys()
• These look like Java or C++ method calls.
• New object classes can easily be defined in
addition to these built-in data-types.
∙ In fact, programming in Python is typically
done in an object oriented fashion.
Defining a Class

∙ A class is a special data type which defines


how to build a certain kind of object.
∙ The class also stores some data items that are
shared by all the instances of this class
∙ Instances are objects that are created which
follow the definition given inside of the class
∙ Python doesn’t use separate class interface
definitions as in some languages
∙ You just define the class and then use it
Methods in Classes

∙ Define a method in a class by including


function definitions within the scope of the
class block
∙ There must be a special first argument self
in all of method definitions which gets bound
to the calling instance
∙ There is usually a special method called
__init__ in most classes
∙ We’ll talk about both later…
A simple class def: student

class student:
“““A class representing a
student ”””
def __init__(self,n,a):
self.full_name = n
self.age = a
def get_age(self):
return self.age
Creating and Deleting
Instances
Instantiating Objects
∙ There is no “new” keyword as in Java.
∙ Just use the class name with ( ) notation and
assign the result to a variable
∙ __init__ serves as a constructor for the
class. Usually does some initialization work
∙ The arguments passed to the class name are
given to its __init__() method
∙ So, the __init__ method for student is passed
“Bob” and 21 and the new class instance is
bound to b:
b = student(“Bob”, 21)
Constructor: __init__
∙ An __init__ method can take any number of
arguments.
∙ Like other functions or methods, the
arguments can be defined with default values,
making them optional to the caller.

∙ However, the first argument self in the


definition of __init__ is special…
Self
∙ The first argument of every method is a
reference to the current instance of the class
∙ By convention, we name this argument self
∙ In __init__, self refers to the object
currently being created; so, in other class
methods, it refers to the instance whose
method was called
∙ Similar to the keyword this in Java or C++
∙ But Python uses self more often than Java
uses this
Self
∙ Although you must specify self explicitly
when defining the method, you don’t include it
when calling the method.
∙ Python passes it for you automatically

Defining a method: Calling a method:


(this code inside a class definition.)

def set_age(self, num): >>> x.set_age(23)


self.age = num
Deleting instances: No Need to “free”

∙ When you are done with an object, you don’t


have to delete or free it explicitly.
∙ Python has automatic garbage collection.
∙ Python will automatically detect when all of the
references to a piece of memory have gone
out of scope. Automatically frees that
memory.
∙ Generally works well, few memory leaks
∙ There’s also no “destructor” method for
classes
Attributes
Two Kinds of Attributes
∙ The non-method data stored by objects are
called attributes
∙ Data attributes
• Variable owned by a particular instance of a class
• Each instance has its own value for it
• These are the most common kind of attribute
∙ Class attributes
• Owned by the class as a whole
• All class instances share the same value for it
• Called “static” variables in some languages
• Good for (1) class-wide constants and (2)
building counter of how many instances of the
class have been made
Data Attributes
∙ Data attributes are created and initialized by
an __init__() method.
• Simply assigning to a name creates the attribute
• Inside the class, refer to data attributes using self
— for example, self.full_name
class teacher:
“A class representing teachers.”
def __init__(self,n):
self.full_name = n
def print_name(self):
print self.full_name
Class Attributes
∙ Because all instances of a class share one copy of a
class attribute, when any instance changes it, the value
is changed for all instances
∙ Class attributes are defined within a class definition and
outside of any method
∙ Since there is one of these attributes per class and not
one per instance, they’re accessed via a different
notation:
• Access class attributes using self.__class__.name notation
-- This is just one way to do this & the safest in general.

class sample: >>> a = sample()


x = 23 >>> a.increment()
def increment(self): >>> a.__class__.x
self.__class__.x += 124
Data vs. Class Attributes

class counter: >>> a = counter()


overall_total = 0 >>> b = counter()
# class attribute >>> a.increment()
def __init__(self): >>> b.increment()
self.my_total = 0 >>> b.increment()
# data attribute >>> a.my_total
def increment(self): 1
counter.overall_total = \ >>> a.__class__.overall_total
counter.overall_total + 1 3
self.my_total = \ >>> b.my_total
self.my_total + 1 2
>>> b.__class__.overall_total
3
Inheritance
Subclasses
∙ A class can extend the definition of another
class
• Allows use (or extension ) of methods and attributes
already defined in the previous one.
• New class: subclass. Original: parent, ancestor or
superclass
∙ To define a subclass, put the name of the
superclass in parentheses after the subclass’s
name on the first line of the definition.
Class Cs_student(student):
• Python has no ‘extends’ keyword like Java.
• Multiple inheritance is supported.
Redefining Methods
∙ To redefine a method of the parent class,
include a new definition using the same name
in the subclass.
• The old code won’t get executed.
∙ To execute the method in the parent class in
addition to new code for some method,
explicitly call the parent’s version of the
method.
parentClass.methodName(self, a, b, c)
• The only time you ever explicitly pass ‘self’ as an
argument is when calling a method of an
ancestor.
Definition of a class extending student
Class Student:
“A class representing a student.”

def __init__(self,n,a):
self.full_name = n
self.age = a
def get_age(self):
return self.age

Class Cs_student (student):


“A class extending student.”
def __init__(self,n,a,s):
student.__init__(self,n,a) #Call __init__ for student
self.section_num = s
def get_age(self): #Redefines get_age method entirely
print (“Age: ” + str(self.age))
Extending __init__

∙ Same as for redefining any other method…


• Commonly, the ancestor’s __init__ method is
executed in addition to new commands.
• You’ll often see something like this in the __init__
method of subclasses:

parentClass.__init__(self, x, y)

where parentClass is the name of the parent’s class.


Special Built-In
Methods and Attributes
Built-In Members of Classes
∙ Classes contain many methods and attributes
that are included by Python even if you don’t
define them explicitly.
• Most of these methods define automatic functionality
triggered by special operators or usage of that class.
• The built-in attributes define information that must be
stored for all classes.
∙ All built-in members have double underscores
around their names: __init__ __doc__
Special Methods

∙ For example, the method __repr__ exists for


all classes, and you can always redefine it
∙ The definition of this method specifies how to
turn an instance of the class into a string
• print f sometimes calls f.__repr__() to
produce a string for object f

• If you type f at the prompt and hit ENTER, then


you are also calling __repr__ to determine what
to display to the user as output
Special Methods – Example

class student:
...
def __repr__(self):
return “I’m named ” + self.full_name
...

>>> f = student(“Bob Smith”, 23)


>>> print f
I’m named Bob Smith
>>> f
“I’m named Bob Smith”
Special Methods

∙ You can redefine these as well:


__init__ : The constructor for the class
__cmp__ : Define how == works for class
__len__ : Define how len( obj ) works
__copy__ : Define how to copy a class

∙ Other built-in methods allow you to give a


class the ability to use [ ] notation like an array
or ( ) notation like a function call
Special Data Items
∙ These attributes exist for all classes.
__doc__ : Variable for documentation string for
class
__class__ : Variable which gives you a reference
to the class from any instance of it
__module__ : Variable which gives a reference to
the module in which the particular class is defined
__dict__ :The dictionary that is actually the
namespace for a class (but not its superclasses)
∙ Useful:
• dir(x) returns a list of all methods and
attributes defined for object x
Special Data Items – Example
>>> f = student(“Bob Smith”, 23)

>>> print f.__doc__


A class representing a student.

>>> f.__class__
< class studentClass at 010B4C6 >

>>> g = f.__class__(“Tom Jones”,


34)
Private Data and Methods
∙ Any attribute/method with 2 leading
under-scores in its name (but none at the end)
is private and can’t be accessed outside of
class
∙ Note: Names with two underscores at the
beginning and the end are for built-in
methods or attributes for the class
∙ Note: There is no ‘protected’ status in Python;
so, subclasses would be unable to access
these private data either.
__new__ method
∙ Whenever a class is instantiated __new__ and
__init__ methods are called.
∙ __new__ method is called to create an object
∙ __init__ method will be called to initialize the
object.
∙ Parameter: cls
∙ cls represents the class that is needed to be
instantiated, and the compiler automatically
provides this parameter at the time of
instantiation.
Architecture
Example
∙ class A(object):
∙ def __new__(cls):
∙ print("Creating instance")
∙ #return object.__new__(cls)
∙ def __init__(self):
∙ print("Init is called")
∙ A()
∙ #Try printing it
∙ What if __init__ returns?
Example 2
∙ class Point:
∙ def __new__(cls, *args, **kwargs):
∙ return super().__new__(cls) __new__ itself can
take only one
∙ def __init__(self, x, y): parameter, cls
∙ self.x = x
∙ self.y = y
∙ def __repr__(self) -> str:
∙ return f"{type(self).__name__}(x={self.x},
y={self.y})“
∙ >>> point = Point(14,23)
∙ >>> point
Returning object
∙ class A(object):
∙ def __str__(self):
∙ return “Stringify a class"
∙ class B(object):
∙ def __new__(cls): __new__ can return
an object of a different
∙ return A() class
∙ def __init__(self):
∙ print("Inside init")

∙ print(B())
Subclassing Immutable Types
∙ class Distance(float):
∙ def __new__(cls, value, unit):
∙ instance = super().__new__(cls, value)
∙ instance.unit = unit
∙ return instance

∙ in_miles = Distance(42.0, "Miles")


∙ print(in_miles)
∙ print(in_miles.unit)
Returning
∙ class Distance(float):
∙ def __new__(cls, value, unit):
∙ instance = super().__new__(cls, value)
∙ instance.unit = unit
∙ return instance

∙ in_miles = Distance(42.0, "Miles")


∙ print(in_miles)
∙ print(in_miles.unit)
What Can You Do With
Decorators?
■ Decorators allow you to inject or modify
code in functions or classes
■ Aspect Oriented Programming
■ suppose you'd like to do something at
the entry and exit points of a function
(such as perform some kind of security,
tracing, locking, etc
Function Decorators
■ @myDecorator
■ def aFunction(): print "inside aFunction“
■ When the compiler passes over this
code, aFunction() is compiled and the
resulting function object is passed to the
myDecorator code, which does something to
produce a function-like object that is then
substituted for the original aFunction().
The decorator class
class myDecorator(object):
def __init__(self, f):
print( "inside myDecorator.__init__()“)
f() # Prove that function definition has
completed
def __call__(self): #Has to be there
print ("inside myDecorator.__call__()“)
The call
@myDecorator
def aFunction():
print "inside aFunction()"
print "Finished decorating aFunction()"
aFunction()
Using Functions as Decorators
def entryExit(f):
def new_f():
print "Entering", f.__name__
f()
print "Exited", f.__name__
return new_f
Implementation
func1()
@entryExit
func2()
def func1():
print func1.__name__
print "inside func1()“
@entryExit
def func2():
print "inside func2()“
Passing parameters
∙ def multiply_numbers(func):
∙ def multiply_two_numbers(num1, num2):
∙ return func(num1, num2)
∙ return multiply_two_numbers

∙ @multiply_numbers
∙ def multiply_two_given_numbers(num1,
num2):
∙ return num1 * num2
∙ print(multiply_two_given_numbers(3, 4))
Decorator chaining 1
∙ def increase_decorator(func):
∙ def increase_by_two():
∙ print('Increasing number by 2')
∙ new_number = func()
∙ return new_number + 2

∙ return increase_by_two
Decorator chaining 2
∙ def decrease_decorator(func):
∙ def decrease_by_one():
∙ print('Decreasing number by 1')
∙ new_number = func()
∙ return new_number - 1
∙ return decrease_by_one
Final code
∙ @increase_decorator
∙ @decrease_decorator
∙ def get_number():
∙ return 5
∙ print(get_number())
Error handling with decorators
∙ def Error_Handler(func):
∙ def Inner_Function(*args, **kwargs):
∙ try:
∙ func(*args, **kwargs)
∙ except TypeError:
∙ print(f"{func.__name__} wrong data
types. enter numeric")
∙ return Inner_Function
Error handling with decorators
∙ @Error_Handler
∙ def Mean(a,b):
∙ print((a+b)/2)
∙ @Error_Handler
∙ def Square(sq):
∙ print(sq*sq)
∙ @Error_Handler
∙ def Divide(l,b):
∙ print(b/l)
Error handling with decorators

∙Mean(4,5)
∙Square(14)
∙Divide(8,4)
∙Square("three")
∙Divide("two","one")
∙Mean("six","five")
Passing params to class
class MyDecorator:
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
self.function(*args, **kwargs)
@MyDecorator
def function(name, message ='Hello'):
print("{}, {}".format(message, name))
function(“Hello", “World")
Passing params to class
class MyDecorator:
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
self.function(*args, **kwargs)
@MyDecorator
def function(name, message ='Hello'):
print("{}, {}".format(message, name))
function(“Hello", “World")

You might also like