天天看点

python基础---面向对象高级

面向对象高级

isinstance(obj,cls)

检查obj是否是类 cls 的对象

<code>class</code> <code>Foo(</code><code>object</code><code>):</code>

<code>    </code><code>pass</code>

<code>obj </code><code>=</code> <code>Foo()</code>

<code>print</code><code>(</code><code>isinstance</code><code>(obj, Foo)) </code>

<code>输出:</code>

<code>True</code>

issubclass(sub,super)

检查sub类是否是 super 类的派生类

<code>class</code> <code>Bar(Foo):</code>

<code>print</code><code>(</code><code>issubclass</code><code>(Bar, Foo))</code>

b.反射

主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

python面向对象中的反射:通过字符串反射到真实的属性上

面向对象中类中属性的两种调用方法:

1.   类名.属性

2.类名.__dict__[‘属性名’] #通过字符串的形式

<code>class</code> <code>Foo:</code>

<code>    </code><code>x</code><code>=</code><code>1</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name):</code>

<code>        </code><code>self</code><code>.name</code><code>=</code><code>name</code>

<code>    </code><code>def</code> <code>f1(</code><code>self</code><code>):</code>

<code>        </code><code>print</code><code>(</code><code>'from f1'</code><code>)</code>

<code>print</code><code>(Foo.x)   </code><code>#方法1Foo.__dict__['x']      #方法2</code>

实现自省的函数,通过操作字符串的方式映射到属性(适用于类和对象,在python中一切皆对象,类本身也是一个对象)

hasattr(obj,’name’)     判断obj中有没有一个name字符串对应的方法或属性

setattr(x,’y’,’v’)     设置函数,x对象名,y属性,v值

getattr(x,’y’)         取值函数,x对象名,y属性

delattr(x,’y’)         删除函数,x对象名,y属性

<code>class</code> <code>Ftpserver:</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,host,port):</code>

<code>        </code><code>self</code><code>.host</code><code>=</code><code>host</code>

<code>        </code><code>self</code><code>.port</code><code>=</code><code>port</code>

<code>    </code><code>def</code> <code>run(</code><code>self</code><code>):</code>

<code>        </code><code>while</code> <code>True</code><code>:</code>

<code>            </code><code>cmd</code><code>=</code><code>input</code><code>(</code><code>'&gt;&gt;: '</code><code>).strip()</code>

<code>            </code><code>if</code> <code>not</code> <code>cmd:</code><code>continue</code>    <code># 判断输入是否为空</code>

<code>            </code><code>if</code> <code>hasattr</code><code>(</code><code>self</code><code>,cmd):   </code><code># 判断类中是否存在此方法</code>

<code>                </code><code>func</code><code>=</code><code>getattr</code><code>(</code><code>self</code><code>,cmd)   </code><code># 取出该方法的值并赋值给func</code>

<code>                </code><code>func()           </code>

<code>    </code><code>def</code> <code>get(</code><code>self</code><code>):</code>

<code>        </code><code>print</code><code>(</code><code>'get func'</code><code>)</code>

<code>    </code><code>def</code> <code>put(</code><code>self</code><code>):</code>

<code>        </code><code>print</code><code>(</code><code>'put func'</code><code>)</code>

反射的好处:

1.实现可插拔机制:

可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能(首先使用hasattr进行判断是否存在此方法,存在则执行,不存在则跳过)

2.动态导入模块(基于反射当前模块成员)

c.item系列

__setitem__      设置函数

__getitem__      取值函数

__delitem__      删除函数

<code>    </code><code>def</code> <code>__getitem__(</code><code>self</code><code>, item):</code>

<code>        </code><code>print</code><code>(</code><code>'=====&gt;get'</code><code>)</code>

<code>        </code><code>return</code> <code>self</code><code>.__dict__[item]</code>

<code>    </code><code>def</code> <code>__setitem__(</code><code>self</code><code>, key, value):</code>

<code>        </code><code>print</code><code>(</code><code>'==============&gt;set'</code><code>)</code>

<code>        </code><code>self</code><code>.__dict__[key]</code><code>=</code><code>value</code>

<code>        </code><code># setattr(self,key,value)</code>

<code>    </code><code>def</code> <code>__delitem__(</code><code>self</code><code>, key):</code>

<code>        </code><code>print</code><code>(</code><code>'============&gt;del'</code><code>)</code>

<code>        </code><code>self</code><code>.__dict__.pop(key)</code>

<code>f</code><code>=</code><code>Foo()</code>

<code>f[</code><code>'x'</code><code>]</code><code>=</code><code>123123123123</code>    <code># 通过f[]的方式对对象进行操作时会调用item方法</code>

<code>print</code><code>(f[</code><code>'x'</code><code>])</code>

<code>del</code> <code>f[</code><code>'x'</code><code>] </code>

<code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>&gt;</code><code>set</code>

<code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>&gt;get</code>

<code>123123123123</code>

<code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>=</code><code>&gt;</code><code>del</code>

d.打印对象信息__str__

<code>class</code> <code>People:</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,name,age,sex):</code>

<code>        </code><code>self</code><code>.age</code><code>=</code><code>age</code>

<code>        </code><code>self</code><code>.sex</code><code>=</code><code>sex</code>

<code>    </code><code>def</code> <code>__str__(</code><code>self</code><code>):                </code><code>#在对象被打印时触发执行</code>

<code>        </code><code>return</code> <code>'&lt;name:%s age:%s sex:%s&gt;'</code> <code>%</code><code>(</code><code>self</code><code>.name,</code><code>self</code><code>.age,</code><code>self</code><code>.sex)</code>

<code>p1</code><code>=</code><code>People(</code><code>'egon'</code><code>,</code><code>18</code><code>,</code><code>'male'</code><code>)</code>

<code>p2</code><code>=</code><code>People(</code><code>'alex'</code><code>,</code><code>38</code><code>,</code><code>'male'</code><code>)</code>

<code>print</code><code>(p1)</code>

<code>print</code><code>(p2)</code>

e.析构方法__del__

当对象在内存中被释放时,自动触发执行

注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__

典型的应用场景:

创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中,当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,x):</code>

<code>        </code><code>self</code><code>.x</code><code>=</code><code>x</code>

<code>    </code><code>def</code> <code>__del__(</code><code>self</code><code>): </code><code>#在对象资源被释放时触发</code>

<code>        </code><code>print</code><code>(</code><code>'-----del------'</code><code>)</code>

<code>        </code><code>print</code><code>(</code><code>self</code><code>)</code>

<code>f</code><code>=</code><code>Foo(</code><code>100000</code><code>)</code>

<code>del</code> <code>f</code>

<code>print</code><code>(</code><code>'=======================&gt;'</code><code>) </code>

<code># 析构方法__del__与文件处理原理差不多:</code>

<code> </code> 

<code>f</code><code>=</code><code>open</code><code>(</code><code>'a.txt'</code><code>)  </code><code>#做了两件事,在用户空间拿到一个f变量,在操作系统内核空间打开一个文件</code>

<code>del</code> <code>f          </code><code>#只回收用户空间的f,操作系统的文件还处于打开状态</code>

<code>#所以我们应该在del f之前保证f.close()执行,即便是没有del,程序执行完毕也会自动del清理资源,于是文件操作的正确用法应该是</code>

<code>f</code><code>=</code><code>open</code><code>(</code><code>'a.txt'</code><code>)</code>

<code>f.close()  </code><code># f.close就相当于析构方法__del__,在回收用户空间的同时回收系统空间</code>

7、异常处理

异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止)

错误有两种:

a.语法错误(在语法检测阶段抛出,必须在程序执行前就改正)

b.逻辑错误

例如:

<code>TypeError      </code><code># 类型错误</code>

<code>for</code> <code>i </code><code>in</code> <code>3</code><code>:</code>

<code>NameError      </code><code># 名称错误</code>

<code>aaaaa</code>

<code>ValueError     </code><code># 值错误</code>

<code>int</code><code>(</code><code>'asdfsadf'</code><code>)</code>

<code>IndexError     </code><code># 索引错误</code>

<code>l</code><code>=</code><code>[</code><code>1</code><code>,</code><code>2</code><code>]</code>

<code>l[</code><code>1000</code><code>]</code>

<code>KeyError       </code><code># key错误</code>

<code>d</code><code>=</code><code>{</code><code>'a'</code><code>:</code><code>1</code><code>}</code>

<code>d[</code><code>'b'</code><code>]</code>

<code>AttributeError </code><code># 属性错误</code>

<code>class</code> <code>Foo:</code><code>pass</code> 

<code>Foo.x</code>

常见异常:

AttributeError      试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

IOError       输入/输出异常;基本上是无法打开文件

ImportError      无法引入模块或包;基本上是路径问题或名称错误

IndentationError      语法错误(的子类) ;代码没有正确对齐

IndexError   下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

KeyError     试图访问字典里不存在的键

KeyboardInterrupt   Ctrl+C被按下

NameError   使用一个还未被赋予对象的变量

SyntaxError Python   代码非法,代码不能编译(个人认为这是语法错误,写错了)

TypeError   传入对象类型与要求的不符合

UnboundLocalError  试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它

ValueError   传入一个调用者不期望的值,即使值的类型是正确的

异常处理

a. 如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防

<code>AGE</code><code>=</code><code>10</code>

<code>while</code> <code>True</code><code>:</code>

<code>    </code><code>age</code><code>=</code><code>input</code><code>(</code><code>'&gt;&gt;: '</code><code>).strip()</code>

<code>    </code><code>if</code> <code>age.isdigit(): </code><code>#只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的</code>

<code>        </code><code>age</code><code>=</code><code>int</code><code>(age)</code>

<code>        </code><code>if</code> <code>age </code><code>=</code><code>=</code> <code>AGE:</code>

<code>            </code><code>print</code><code>(</code><code>'you got it'</code><code>)</code>

<code>            </code><code>break</code>

b. 如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理

异常类只能用来处理指定的异常情况,如果非指定异常则无法处理

<code>try</code><code>:</code>

<code>    </code><code>aaaa        </code><code># 抛出NameError异常</code>

<code>    </code><code>print</code><code>(</code><code>'==-==&gt;1'</code><code>)</code>

<code>    </code><code>l</code><code>=</code><code>[]</code>

<code>    </code><code>l[</code><code>3</code><code>]        </code><code># 抛出IndexError异常</code>

<code>    </code><code>print</code><code>(</code><code>'==-==&gt;2'</code><code>)</code>

<code>    </code><code>d</code><code>=</code><code>{}</code>

<code>    </code><code>d[</code><code>'x'</code><code>]      </code><code># 抛出KeyError异常</code>

<code>    </code><code>print</code><code>(</code><code>'==-==&gt;3'</code><code>) </code>

<code># 多分支异常</code>

<code>except</code> <code>NameError as e:</code>

<code>    </code><code>print</code><code>(e)</code>

<code>except</code> <code>IndexError as e:</code>

<code>except</code> <code>KeyError as e:</code>

<code>except</code> <code>Exception as e:       </code><code># 万能异常,能捕捉到所有的异常</code>

<code>else</code><code>:</code>

<code>    </code><code>print</code><code>(</code><code>'在没有错误的时候执行'</code><code>)</code>

<code>finally</code><code>:</code>

<code>    </code><code>print</code><code>(</code><code>'无论有无错误,都会执行'</code><code>)</code>

c.主动抛出异常

<code>    </code><code>raise</code> <code>TypeError(</code><code>'类型错误'</code><code>)</code>

<code>except</code> <code>Exception as e:</code>

d.自定义异常

<code>class</code> <code>EgonException(BaseException):</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,msg):</code>

<code>        </code><code>self</code><code>.msg</code><code>=</code><code>msg</code>

<code>    </code><code>def</code> <code>__str__(</code><code>self</code><code>):</code>

<code>        </code><code>return</code> <code>'&lt;%s&gt;'</code> <code>%</code><code>self</code><code>.msg</code>

<code>raise</code> <code>EgonException(</code><code>'egon 的异常'</code><code>)</code>

e.断言

assert

本文转自lyndon博客51CTO博客,原文链接http://blog.51cto.com/lyndon/1961399如需转载请自行联系原作者

迟到的栋子