python面向对象编程
类的对象和实例对象
-
类对象:默认行为,是实例对象的工厂
-
实例对象:程序处理的实际对象
class A: """ class A here """ def setname(selef,name) self.name = name pass
类中的方法第一个参数self指的是当实例在调用这个方法时,self就是这个实例本身
创建实例对象的方法(下面的语句会自动调用一个类对象都会自带的构造方法这样就生成了一个类的实例)a = A()
构造函数
- 语法:
- def _ init _(self, *args):
- pass
- def _ init _(self, *args):
-
_ init _ 构造函数,
- 具有初始化的作用,也就是该类被实例化的时候就会执行的函数
-
可以把要先初始化的属性放到这个函数里
class Persion: """ persion defined """ def ___init__(self, name,age): self.name = name self.age = age print 'constructor is called'
析构函数
- 语法
- def _ del _(self):
- < statement >
- def _ del _(self):
-
_ del _析构函数
- 使用del删除对象是,会调用他本身的析构函数
- 当对象在某个作用域中调用完毕,
-
在跳出某个作用域的同时析构函数也会调用一次,这样可以释放出内存空间。
class Person: """ person defined """ def __del__(self): print 'destructor is called'
运算符重载
- 打印显示
- def _ str _(self):
- < statement >
- def _ str _(self):
-
_ str _
- 每当实例转换成打印字符串的时候, _ str _自动运行(即print这个实例的时候)
-
_ repr _
-
当直接运行这个实例时所要显示的内容
class Person: """ person defined """ def __str__(self): return 'Peson name:%s and age: %d' %(self.name, self.age) def __repr__(self): return '[REPR]Person name:%s and age:%d' %(self.name,self,age)
-
- 语法:
类可以重载加法减法运算、打印、函数调用、索引等内置运算,运算符重载使我们的对象行为与内置对象的一样。Python在调用操作符时会自动调用这样的方法。
- 索引和分片:_ getitem _ 和 _ setitem _ (即[]{}列表元组的运算)
- 属性引用: _ getattr _ 和 _ setattr _ (即点号的运算)
- 比较: _ it _ 、 _ get _ 和其他方法
- 类可以定义方法来捕捉所有的6种比较运算符: < 、 > 、 <=、 ==、 和 !=。这些方法通常很容易使用
运算符重载 - 索引迭代
class stepper:
def __getitem__(self,i):
return self.data[i]
X = stepper()
X.data = "Spam"
print X[1]
运算符重载 - 属性引用
getattr 这个方法是在属性不存在的时候会调用这个方法
class empty:
del __getattr__(self,attrname):
if attrname = "age":
return 40
else:
raise AttributeError,attrname
X = empty()
X.age
类的继承
类可以继承父类属性
-
语法:
- class 类名(父类)
-
继承
- 子类可以继承父类的所有方法和属性
- 可以重载父类的成员函数和属性
-
必须注意的是子类成员函数若重载父类,会使用子类的成员函数
class Chiness(Person): pass
class CAnimal:
def __init__(self,voice='hello'):
self.voice = voice
def Say(self):
print self.voice
def Run(self):
pass
class CDog(CAnimal):
def SetVoice(self,voice):
self.voice = voice
def Run(self):
print 'Running'
dog = CDog()
dog.SetVoice('I am a dog!')
子类继承父类后,子类中的方法重载了父类的方法,那么就会在子类运行子类重载的方法,这就是多态的体现
类的继承搜索与多重继承
- 属性继承搜索
- Python的属性搜索是按继承树从上到下进行的。
- 继承树以类对象为中心,向上是其基类,向下使其实例对象。
- 当通过实例.属性的方式访问某属性时
- 首先查找实例对象自身是否存在该属性
- 如果存在,那么直接返回
- 如果不存在,那么向上查找,直到找到为止,否则返回异常
类的静态方法和类方法
- 类方法是只能由类名来调用
- 静态方法可以由类名或对象名进行调用
-
两种方法的主要区别在于参数
- 实例方法隐含的参数为类实例self
- 类方法隐含的参数为类本身cls
- 静态方法无隐含参数,主要为了类实例也可以直接调用静态方法
-
逻辑上类方法应当只被类调用,实例方法实例调用,静态方法两者都能调用
@staticmethod def callStatic() print 'static call' @classmethod def callClass(cls): print 'class all'
class TestClass():
def callFunc(self):
print 'callfunc'
@staticmethod
def callStatic():
print 'static call'
@classmethod
def callClass(cls):
print 'class call'
c = TestClass()
c.callFunc()
c.callStatic()
c.callClass() # c的实例去调用这三个方法都可以调用
TestClass.callFunc() # 类名不能调用实例方法,只能调用下面两个类方法和静态方法
TestClass.callStatic()
TestClass.callClass()
普通的方法,第一个参数需要是self,它表示一个具体的实例本身。
如果用了staticmethod,那么就可以无视这个self,而将这个方法当成一个普通的函数使用。
而对于classmethod,它的第一个参数不是self,是cls,它表示这个类本身.
新式类
- Python2.X中默认的都是经典类,只有显式继承了object才是新式类
- Python3.X中默认的都是新式类,不用显式继承object
-
区别:
- 新式类对象可以直接通过_ class _属性获取自身类型
- 继承搜索的顺序发生了变化
- 经典类多继承属性搜索顺序:先深入继承树左侧,再返回,开始找右侧;
- 新式类多继承属性搜索顺序:先水平搜索,然后在向上移动
新式类增加了 _ slots 内置属性,可以把实例属性的种类锁定到 slots _规定的范围之中
-
新式类增加了_ getattribute _方法 (此方法是点操作,无论有没有此属性都触发的方法)
class A(object): """ 新式类 作为所有类的基类 """ def foo(self): print "class A" class A1(): """ 经典类 作为所有类的基类 """ def foo(self): print "class A1" class C(A): pass class C1(A1): pass class D(A): def foo(self): print "class D" class D1(A1) def foo(self): print "class D1" class E(C, D): pass class E1(C1, D1): pass e = E() e.foo() e1 = E1() e1.foo() print
类的私有属性
-
类的私有属性
- _ private_attrs:两个下划线开头的,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self._ private_attrs.
-
类的私有方法
- __ private_method:两个下划线开头,声明该方法为私有,不能在类的外部调用。在类内部调用 self.__private_methods
异常
- 查看异常类 dir(_ builtins _)
异常处理器
- 默认异常处理器
- 代码没有捕捉这个异常,向上返回到程序顶层,默认的异常处理器
- 打印错误信息,并且包含异常和堆栈的跟踪
Try Except 处理器
x, y = 5, 0
try:
x/y
except ZeroDivisionError:
print 'error'
引发异常
-
触发异常
- 异常可以通过Python或者程序引发,也能手动触发异常
-
raise [Exception [, args [, traceback]]]
try: raise ZeroDivisionError except ZeroDivisionError as e: print 'exception got'
except
- 可以不列出异常名称 例如 except:
- 可以捕获多个异常 例如 except(ex1, ex2, ex3)
- 可以分开捕获多个异常 例如 except ex1, except ex2
- 捕获异常并取得额外数据
assert 1==1
assert 1==0
with/as语句
- 常见的try/finally替代方案
- 例如:
- 自动关闭文件
- 对锁的自动上锁和开锁
- with expression [as variable]:
- with - block
- 打开文件例子
环境管理协议
- 定义:上下管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明_ enter 和 exit _方法
- enter(self)
- 出现with语句,对象就会触发_ enter _,其返回值就会赋给as后的变量名
-
exit(self, exc_type, exc_val, exc_tb)
- with代码执行结束后,会执行_ exit _。
-
用途
- 使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无需手动干预
- 在需要管理一些资源比如文件,网络连接锁的编程环境中,可以在_ exit _中定制自动释放资源的机制,你无须再去关心这个问题,这将大有用处