Skip to content

Instantly share code, notes, and snippets.

@ovidiucs
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ovidiucs/03d4021c94abb0d05b30 to your computer and use it in GitHub Desktop.
Save ovidiucs/03d4021c94abb0d05b30 to your computer and use it in GitHub Desktop.
Explaining Classes
class MyClass(object):
"""A simple class example"""
# Class OBJECTS support two kinds of operations
# 1. Attribute reference
# 2. Instantiation
i = 12345
def something(self):
print 'printing - hello world'
return "returning - Hi"
# Class instantiation uses function notation
# The instantiation operation is below - aka - "Calling a class object"
x = MyClass()
y = MyClass()
# The above creates a new instance of the class and assigns this object to the local
# variables x and y
# MyClass.i AND MyClass.f are valid attribute references
# MyClass.i returns function object
print 80*'='
print "x is at {0}\ny is at {1}\nMyClass is at {2} \nCall x.something() returns : {3}\n" \
"x.something is a: {4}\nCall y.something() returns : {5}\n" \
"y.something is a: {6}".format(x,y,MyClass(), x.something(), x.something, y.something(), y.something)
print 80*'='
# x is at <__main__.MyClass object at 0x7ffa5ce8f050>
# y is at <__main__.MyClass object at 0x7ffa5cea8290>
# MyClass is at <__main__.MyClass object at 0x7ffa5cea82d0>
# Call x.something() returns : Hi
# x.something is a: <bound method MyClass.something of <__main__.MyClass object at 0x7ffa5ce8f050>>
# Call y.something() returns : Hi
# y.something is a: <bound method MyClass.something of <__main__.MyClass object at 0x7ffa5cea8290>>
# ================
# Class ATTRIBUTES can also be assigned to, so you can change the value of MyClass.i by assignment
x.i = 54321
y.i = 1000
# 54321 1000 12345
print x.i, y.i, MyClass.i
# Classes create objects. The special method __init__() create objects with
# instances customized to a specific initial state
class AnotherClass(object):
def __init__(self):
self.data = []
# When we instantiate the above class it will automatically invoke __init__()
# for the newly created class instance
print 80*'='
x1 = AnotherClass()
y1 = AnotherClass()
print x1.data
x1.data = [1,1,1,3,3,3]
y1.data = [3,3,3,1,1,1]
# [1, 1, 1, 3, 3, 3] [3, 3, 3, 1, 1, 1]
print x1.data, y1.data
# The __init__ method may have arguments for greater flexibilty
class AClass(object):
def __init__(self,num1,num2):
self.add = num1 + num2
# TypeError: __init__() takes exactly 3 arguments (1 given)
# x2 = AClass()
x2 = AClass(3,4)
# 7
print x2.add, type(x2), type(x2.add)
# ================
# Instance Objects
# The only operations understood by instance objects are attribute references.
# Two kinds of valid attribute names:
# 1. Data attributes
# 2. Methods
# 1. Corresponds to "instance variables"
# - They need not be declared like local variables
# - They spring into existence when they are first assigned to
x.counter = 1
print 80*'-'
while x.counter < 10:
x.counter = x.counter * 2
# 16
# ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__',
# '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '
# __sizeof__', '__str__', '__subclasshook__', '__weakref__', 'counter', 'i', 'something']
print x.counter, dir(x)
del x.counter
# 2. A METHOD is a function that "belongs to" an object
# - not unique to class instances (list objects have "append", "insert", "remove", ... etc.
# x.something is a valid method reference since MyClass.f is a function, x.1 is not.
# x.something is not the same thing as MyClass.f - it's a method object, not a FUNCTION object
# ================
# Method objects
# Usually a method is called right after it is BOUND
#x.something()
# - It is not necessary to call a method right away
# - x.something is a METHOD OBJECT. It can be stored away and called at a LATER time
xs = x.something
print 80*'-'
if True:
print "Condition is true and I'm calling the method {0}".format(xs())
# xs was CALLED without an argument
# the OBJECT is passed as the first arguments of the function
# when an instace attribute is referenced that isn't a data attribute,
# its calss is searched. If the names denotes a VALID class attribute that is a FUNCTION object
# a method object is created by pointing to the instance object
# ================
# Class and instance variables
# Instance variables - DATA unique to each INSTANCE
# Class variables - for attributes and methods shared by ALL instances of the class
class Dog(object):
kind = 'canine' # class variable shared by all instances
def __init__(self, dogname):
self.name = dogname # instance variable unique to each instance
d1 = Dog('Fido') # unique to d1
d2 = Dog('Lassie') # unique to d2
# Fido Lassie canine canine
print d1.name, d2.name, d1.kind, d2.kind
# ================
# Adding tricks to DOG class
class DogWithTricks():
kind = 'canine' # class variable shared by all instances
# tricks = [] # INCORRECT - a single list shared by all DogWithTricks instances
def __init__(self, dogname):
self.name = dogname # instance variable unique to each instance
self.tricks = [] # create a new empty list for EACH dog
# correct use
def add_trick(self,trick):
self.tricks.append(trick)
d3 = DogWithTricks('Frodo')
d3.add_trick('play dead')
d3.add_trick('rollover')
# Frodo is the dog name and it knows ['play dead', 'rollover'] tricks
print "\n{0} is the dog name and it knows {1} tricks".format(d3.name,d3.tricks)
# Methods may call other methods by using method attributes of the self argument:
class Bag(object):
def __init__(self):
self.data = []
def add(self,x):
self.data.append(x)
def addtwice(self,x):
self.add(x)
self.add(x)
bag1 = Bag()
bag1.add('gem')
bag1.addtwice('cascaval')
print "In punga am {0}".format(bag1.data)
# Methods may reference global names in the same way as ordinary functions
# It is not necessary that the function definition is textually enclosed
# in the class definition: assigning a function object to a local variable in the class is also ok.
# ================
# Inheritance
class BaseClassName(object):
pass
class DerivedClassName(BaseClassName):
#<statement-1>
#.
#.
#.
#<statement-N>
pass
# When the class object is constructed, the base class is remembered.
# This is used for resolving attribute references. If a requested attributed is not found in the class, the
# search proceeds to look in the base class
# DERIVED classs MAY override methods of their base class
# Built-in functions that work with inheritance:
# 1. isinstance() to check an instance type isinstance(obj, int) will be True only if obj.__class__ is int
# 2. issubclass() to check class inheritance issubclass(bool, int) is True since bool is a subclass of int
# ================
# Multiple Inheritance
# Old style classes : the only rule is depth-first, left-to-right.
# Private variables and Class-local References
# name prefixed with an underscore (e.g. _spam)
# should be treated as a non-public part of the API
# (whether it is a function, a method or a data member)
# to avoid name clashes of names with names defined by subclasses
# Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore)
# is textually replaced with _classname__spam, where classname is the current class name with leading
# underscore(s) stripped
class Mapping(object):
def __init__(self, iterable):
self.items_list = []
self.__update(iterable)
def update(self, iterable):
for item in iterable:
self.items_list.append(item)
__update = update # private copy of original update() method
class MappingSubClass(Mapping):
def update(self, keys, values):
# provide new signature for update()
# but does not break __init__()
for item in zip(keys, values):
self.items_list.append(item)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment