三个特性:
1.多态
object.function(),对象的函数是方法
多态就是:不必知道对象类型,只在乎对对象进行操作。
使用 type(), isinstance(), issubclass() 等毁掉多态——多态实际上并不care是什么类型。
2.封装
3.继承
所有对象都属于某一类,成为类的实例(instance)。
subclass( superclass )
类:
1. 类的定义 = 执行代码块
class C:
print 'Class C has ben defined and execute...'
init 初始化类作用域内的变量:class MemberCounter:
members = 0 #member,类中的全局变量
def init(self):
MemberCounter.members += 1
print self.members,MemberCounter.members
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
2.类的命名空间
当给实例中的属性进行重新赋值的时候,改变的只有被赋值的实例——相当于函数的屏蔽。
class MemberCounter:
members = 0
def __init__(self):
MemberCounter.members += 1
#self.members += 1
m1 = MemberCounter()
print m1.members
m2 = MemberCounter()
print m2.members,m1.members
注意上面的 self.members 是针对每一个实例,这个在创建实例的时候不会影响到其他的实例的值
MemberCounter.members 则是针对类,只要创建实例,这个类型的member变量就会 +1,在创建新实例的时候就会影响到其他实例的值。
m1.members = 'Two' # 改变的是属于 m1 的members
print m1.members,m2.members
上面代码中,新members的值写到了m1中,屏蔽了类范围内的变量,同 函数内的局部变量,全局变量类似
3. 新式类: __metaclass__ = type确保类是新型的
如果想知道一个对象是什么类
strx = 'hello'
print strx.__class__
有 __metaclass__ = type/从object 继承的方式来定义新式类,可以使用 type(x) 查看示例所属的类。
# -*- coding: utf-8 -*-
__metaclass__ = type # 确定使用新式类—需要在模块/脚本开始的地方放置
class Person:
def setName(self,name):
self.name = name
def getName(self):
return self.name
def greet(self):
print 'Hello, world! I am %s' % self.getName() #self.name 类内部可以直接访问,使用方法一般实在类外部
foo = Person()
foo.setName('Jack')
foo.greet()
bar = Person()
bar.setName('Lucy')
bar.greet()
4. self
注意到每个函数(实际上应该称之为方法,更专业一点:绑定方法)都会有一个self 的参数,self 就是指对象自身,也是函数和方法的区别(函数不需要self,而方法则必须有self ),使用self 将此方法绑定到对应的实例上面。self 参数并不依赖于调用方法的方式:
# -*- coding: utf-8 -*-
class Bird:
song = 'Hahahahah'
def sing(self):
print self.song # 还是会对self进行访问,依旧绑定到类的相同实例上
bird = Bird()
bird.sing()
birdsong = bird.sing # no bracket,依旧绑定到类的相同实例bird上
birdsong()# 赋值没有(),调用有()
将方法变为普通函数:
# -*- coding: utf-8 -*-
class Class:
def method(self):
print 'I have a self'
def function():
print 'I do not..'
instance = Class()
instance.method()
instance.method = function # 赋值没有括号
instance.method()
a.关于私有化
在属性/方法前面加上双下划线,私有化的目的也许是可以是每一次访问都安全,可以对每一次改变通过方法做出通知,而如果直接改变则没有办法获知。
# -*- coding: utf-8 -*-
class Secretive:
def __inanccessible(self):
print 'Access denied'
def accessible(self):
print 'Access:',self.__inaccessible() # 这样就可以访问私有变量了
5. 超类
class Filter:
def __init__(self):
self.blocked = []
def filter(self,sequence):
return [x for x in sequence if x not in self.blocked]
class SPAMFilter(Filter):
def __init__(self):
self.blocked = ['SPAM']
f = Filter()
print f.filter(['SPAM','SPAM', 1,2,'SPAM'])
s = SPAMFilter()
print s.filter(['SPAM','SPAM', 1,2,'SPAM'])
在class语句后面的括号里指定超类6. 使用 getattr 替代 在if 语句内使用 hasattr 函数直接访问特性
getattr 允许提供默认值,以便在特性不存在的时候使用,然后对返回的对象适用callalbe函数,比在if 中使用 hasattr 好的多:
callable( getattr( instance,attribute, default_value) ) 或者 callable( setattr( instance,attribute, default_value) )
if hasattr( istance,attribute )