-
class members (including data members) are public
-
all member functions are virtual
-
method function,
- declared with an explicit first argument representing the object
- the object is provided implicitly by the function call
-
classes are objects
-
Built-in types can be used as base classes
-
Operator overloading supported
-
namespace, mapping from names to objects
- created at different moments, have different lifetimes
- A module's global namespace, created when the module is read in
- function's local namespace, created when the function is called, deleted when the function returns or raises exceptions
-
scope, textual region where a namespace is directly accessible
- statically determined, dynamically used: during execution, 3 nested scopes whose namespace are directly accessible:
- the innermost scope, searched first, contains local names
- the scope of any enclosing functions, 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) in the namespace containing built-in names
- statically determined, dynamically used: during execution, 3 nested scopes whose namespace are directly accessible:
class ClassName:
<statement-1>
.
.
.
<statement-N>
- Support two operations: attribute reference, instantiation
-
attribute reference,
obj.name
; Valid attribute names are all the names in the class's namespace.class MyClass: i = 12345 def f(self): return 'hello world'
MyClass.i
, return an integerMyClass.f
, return a function object
-
instantiation, uses function notation
x = MyClass()
-
__init__()
, create objects customized to specific initial statedef __init__(self): self.data = []
-
__init__()
, may have argumentsclass Complex: def __init__(self, real, img): self.r = real self.i = img x = Complex(3.0, -4.5) x.r, x.i
-
-
- attribute reference, only operation
- Two kingds of valid attribute names, data attribute, method
-
data attribute, data members. Need not be declared
x = MyClass() x.counter = 1 while x.counter < 10: x.counter = x.counter * 2 print x.counter del x.counter
-
method, a class, all function objects define correponding methods of its instances.
x.f
method reference, sinceMyClass.f
is a functionx.i
is not, sinceMyClass.i
is not
-
x.f
, method object, can be stored away and called laterxf = x.f while True: print xf()
- object passed as the first argument of the function,
x.f()
equivalent toMyClass.f(x)
- an instance attribute is referenced that isn't a data attribute, its class is searched.
- the name denotes a valid function object, a method object is created
- a method object is created by pointers to the instance object and the function object found together in an abstract object
-
Data attribute override method attributes
- Use some conventions to minimizes the chances of conflicts
- capitalizing method names
- prefixing data attribute names with a small unique string (underscore)
- using verbs of methods and nouns for data attributes
- Use some conventions to minimizes the chances of conflicts
-
No data hiding, data attributes can be referenced by anyone
-
self
, also a convention, no special meaning to Python. So function definition is not necessarily textually enclosed in class definitiondef f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
f
,g
,h
are all attributes ofC
-
class DerivedClass(modename.BaseClass):
-
Derived classs, may override methods of their base classes
- extend the base class method,
BaseClass.methodname(self, arguments)
- extend the base class method,
-
isinstance()
, check an instance's type,isinstance(obj, int)
-
issubclass()
, check class inheritance,issubclass(bool, int)
class DerivedClass(Base1, Base2, Base3):
-
Convention: a name prefixed with a underscore
_spam
should be treated as private -
name mangling,
__spam
(at least tow leading underscores, at most one trailing underscore), textually replaced with_classname__spam
- helpful letting subclass override methods without breaking intraclass method calls
class Mapping: def __init__(self, iterable): self.items_list = [] self.__update(iterable) def update(self, iterable): for item in iterable: self.item_list.append(item) __update = update # private copy of original update() method class MappingSubclass(Mapping): def update(self, key, values): # provides new signature for update() # but does not break __init__() for item in zip(keys, values): self.items_list.append(item)
-
for
statement callsiter()
on the container object -
iter()
returns an iterator object; definesnext()
, accessing elements one at a timeclass Reverse: """Iterator for looping over a seq backwards.""" def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] rev = Reverse('spam') iter(rev)
-
simple powerful tool for creating iterators
-
written like regular functions, but use the
yield
whenever return data -
each time
next()
called, the generator resumes where it lef-offdef reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] for char in reverse('golf'): print char
- Simple generators, coded succinctly as expression using a syntax similar to list comprehensions but with parentheses
- more compact, less versatile
sum(i*i for i in range(10))
xv = [10, 20, 30]
yv = [7, 5, 3]
sum(x*y for x,y in zip(xv, yv))
from math import pi, sin
sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))
unique_words = set(word for line in page for word in line.split())
valedictorian = max((student.gpa, student.name) for student in graduates)
data = 'golf'
list(data[i] for i in range(len(data)-1, -1, -1))