Python之路【第六篇】:面向对象编程相关
判断类与对象关系
isinstance(obj, cls)
判断对象obj是否是由cls类创建的
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- class Foo(object):
- pass
- obj = Foo()
- print isinstance(obj, Foo)
- #输出结果:True
- #如果对象obj是由Foo类创建的,那么就会返回True 否则返回False
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- class Foo(object):
- pass
- class Boo(object):
- pass
- obj = Boo()
- print isinstance(obj,Foo)
- #输出结果:False
issubclass(Boo, Foo)
检查Boo类是否是 Foo类的派生类
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- class Foo(object):
- pass
- class Boo(Foo):
- pass
- print issubclass(Boo,Foo)
- #同理如果Boo,是Foo的派生类那么返回True
异常处理
一、异常处理的作用
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!(这里的大黄页通常是写代码是用户访问网页,如果出现错误之后返回的一个黄色的报错页面通常称为:大黄页)
例子:
拿咱们刚开始学的时候遇到的问题来举例:
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- str_input = 'tianshuai'
- number = int(str_input)
- print number
- 报错信息:
- '''
- Traceback (most recent call last):
- File "C:/Github/homework/tianshuai/boke.py", line 5, in <module>
- number = int(str_input)
- ValueError: invalid literal for int() with base 10: 'tianshuai'
- '''
上面的信息是不是非常的不友好!
用异常处理来做:
- try:
- str_input = 'tianshuai'
- number = int(str_input)
- print number
- except Exception,e:
- print "\033[32;1m出现错误如下\033[0m"
- print e
- #输出结果:
- '''
- 出现错误如下
- invalid literal for int() with base 10: 'tianshuai'
- '''
二、异常处理基础
拿下面的代码来说:
假如我有一个程序,获取用户输入的数字!这里我不能控制用户输入什么。
看下面输入了一个字符串,这里我可不可以用异常处理来告诉用户,你的输入字符串啊!
- user_input = raw_input("\033[32;1m请输入数字:\033[0m")
- number = int(user_input)
- #请输入数字:sdlkf
- '''
- Traceback (most recent call last):
- File "E:/ѧϰ/GitHub/homework/tianshuai/master.py", line 5, in <module>
- number = int(user_input)
- ValueError: invalid literal for int() with base 10: 'sdlkf'
- '''
假如我使用异常处理:
- try:
- #正常逻辑代码
- user_input = raw_input("\033[32;1m请输入数字:\033[0m")
- number = int(user_input)
- except Exception,e: #这个e是对象Exception类创建的!Exception这里面封装了你上面逻辑块出现问题的所有错误
- #逻辑代码出现错误,这里的代码块就是如果上面的代码出现问题之后执行这个代码块的内容
- print e #如果这个e你不想要,可以自己定义
- #这里也可以记录日志,把错误的详细记录,错误详细在e里了!
- #结果:
- '''
- 请输入数字:sdfs
- invalid literal for int() with base 10: 'sdfs'
- '''
三、异常处理种类
- AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
- IOError 输入/输出异常;基本上是无法打开文件
- ImportError 无法引入模块或包;基本上是路径问题或名称错误
- IndentationError 语法错误(的子类) ;代码没有正确对齐
- IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
- KeyError 试图访问字典里不存在的键
- KeyboardInterrupt Ctrl+C被按下
- NameError 使用一个还未被赋予对象的变量
- SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
- TypeError 传入对象类型与要求的不符合
- UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
- 导致你以为正在访问它
- ValueError 传入一个调用者不期望的值,即使值的类型是正确的
常用异常处理
- ArithmeticError
- AssertionError
- AttributeError
- BaseException
- BufferError
- BytesWarning
- DeprecationWarning
- EnvironmentError
- EOFError
- Exception
- FloatingPointError
- FutureWarning
- GeneratorExit
- ImportError
- ImportWarning
- IndentationError
- IndexError
- IOError
- KeyboardInterrupt
- KeyError
- LookupError
- MemoryError
- NameError
- NotImplementedError
- OSError
- OverflowError
- PendingDeprecationWarning
- ReferenceError
- RuntimeError
- RuntimeWarning
- StandardError
- StopIteration
- SyntaxError
- SyntaxWarning
- SystemError
- SystemExit
- TabError
- TypeError
- UnboundLocalError
- UnicodeDecodeError
- UnicodeEncodeError
- UnicodeError
- UnicodeTranslateError
- UnicodeWarning
- UserWarning
- ValueError
- Warning
- ZeroDivisionError
- 更多异常
更多异常
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- #例子1
- list = ["wupeiqi", 'alex','luotianshuai']
- try:
- list[10]
- except IndexError, e:
- print e
- #异常处理提示:list index out of range
- #例子2
- dic = {'k1':'v1'}
- try:
- dic['k20']
- except KeyError, e:
- print e
- #异常处理提示:'k20'
- #例子3
- s1 = 'hello'
- try:
- int(s1)
- except ValueError, e:
- print e
- #异常处理提示:invalid literal for int() with base 10: 'hello'
实例
对于上面的,异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。如果是int('qew'),你用的是IndexError
异常不是他的异常处理,就会直接报错
- # 未捕获到异常,程序直接报错
- s1 = 'hello'
- try:
- int(s1)
- except IndexError,e:
- print e
- '''
- 报错结果:
- Traceback (most recent call last):
- File "E:/ѧϰ/GitHub/homework/tianshuai/master.py", line 8, in <module>
- int(s1)
- ValueError: invalid literal for int() with base 10: 'hello'
- '''
写程序的时候需要考虑所有可能出现的异常,可以这么写:
- s1 = 'hello'
- try:
- int(s1)
- except IndexError,e:
- print e
- except KeyError,e:
- print e
- except ValueError,e:
- print e
- except Exception,e: #用这个万能的异常去捕获异常
- print e
上面的例子:如果第一个异常触发了就直接返回异常,如果没有触发会去下一个查找,依次查找,到最后的万能异常!
那可能就会有疑问,既然我们有这个万能异常其他的是否是不是就可以不用了呢?
答:当然不是,比如你需要对某一种异常进行特殊处理或提醒的异常,你需要单独拿出来放在Exception前面进行单独的处理!比如日志、提醒等!
- s1 = 'hello'
- try:
- int(s1)
- except KeyError,e:
- print '键错误'
- except IndexError,e:
- print '索引错误'
- except Exception, e:
- print '错误'
四、主动触发异常
比如我现在有一个连接数据库的模块,如果无法连接数据库的时候,这个会影响我剩下所有代码的进行,这时我需要主动去触发一个异常!
mysql_contrl.py
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- def connect():
- return False #无法连接数据库报错(假设无法连接数据库返回False)
主代码
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- import model
- if __name__ == '__main__':
- try:
- result = model.connect()
- if result:
- print "\033[32;1m连接成功\033[0m"
- else:
- raise Exception('\033[31;1m无法连接数据库\033[0m')#无法连接的时候主动触发一个异常,这个异常的明细,是我自己来指定的
- except Exception,e:
- print e
五、异常其他结构
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- try:
- #这一块才是最主要的逻辑处理块,所有的逻辑处理都是放在这里的
- pass
- except KeyError,e:#如果出现KeyError错误,首先被他捕获,下面的except就不执行了
- pass
- except Exception,e:#如果上面的错误没有找到就去,万能异常里找
- pass
- else:#这里什么时候执行呢,逻辑代码里为出现异常这个代码快才执行
- pass
- finally: #不管上面是否出现异常,最后执行完之后,这里永远执行!finally什么时候用?你上面执行一个操作,连接数据库,我这里就可以执行,断开数据库释放资源!(举例)
- pass
- '''
- 上面的代码就是全部的异常处理的内容
- '''
六、自定义异常
咱们看下异常处理的代码!咱们这里知道e是一个对象,这个e是由Exception类创建的,咱们print这个e是一个字符串,那么这个字符串是怎么来的呢?
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- try:
- int('sdfsdfs')
- except Exception,e:
- print e
- #执行结果:
- '''
- invalid literal for int() with base 10: 'sdfsdfs'
- '''
在看这个代码
- class A(object):
- pass
- obj = A()
- print obj
- #执行结果:
- '''
- <__main__.A object at 0x0000000000AA2A20>
- '''
嗯?这是为什么呢?这个咱们应该知道的,在学面向对象的时候类有一个__str__方法
__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- class A(object):
- pass
- def __str__(self):
- return "shuaige is so handsome"
- obj = A()
- print obj
- #执行结果:
- '''
- shuaige is so handsome
- '''
OK既然我们知道异常的原理了,当我们print “e”的时候是调用的__str__方法我们也就可以自己写一个异常了!
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- class Shuaigeerror(Exception):#自己定义一个异常并继承Exception,除了自己定义的异常Exception的万能异常也可以使用
- def __init__(self,msg=None):
- self.msg = msg
- def __str__(self):
- if self.msg:
- return self.msg #定义了错误了信息提示的错误
- else:
- return 'something error' #默认如果不传参数的时候提示的错误
- try:
- raise Shuaigeerror('shuaige is handsome')
- except Exception,e:
- print e
- #输出结果
- '''
- shuaige is handsome
- '''
七、断言
- assert 1 == 1 #如果条件满足就不报错,如果条件不满足就会报错
- assert 1 == 2
- '''
- 这个和 raise Exception('string') 只要你定义了raise肯定会报错
- 这个一般什么时候使用,比如我写了一个软件,上面有些条款:
- 你必须接受,你不接受我就不让你用!
- '''
反射
python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
首先看下对象的操作:
- class Foo(object):
- def __init__(self):
- self.name = 'wupeiqi'
- def func(self):
- return 'func'
- obj = Foo()
- # #### 检查是否含有成员 ####
- hasattr(obj, 'name')
- hasattr(obj, 'func')
- # #### 获取成员 ####
- getattr(obj, 'name')
- getattr(obj, 'func')
- # #### 设置成员 ####
- setattr(obj, 'age', 18)
- setattr(obj, 'show', lambda num: num + 1)
- # #### 删除成员 ####
- delattr(obj, 'name')
- delattr(obj, 'func')
python中一切实物都是对象,类、模块也是对象!反射是通过字符串的形式操作对象相关的成员!
实例:
我有两个web模块:web1,web2,里面包含了所有用户的跳转页面!web1包含了所有用户的登录跳转 web2里包含了所有用户的认证跳转
模块代码:
- #web1
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- def login1():
- return 'web1.login'
- #web2
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- def authentication():
- return 'web2.authentication'
主代码:
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- models,action = raw_input("请输入URL:").split('/')
- model = __import__(models)
- '''
- 咱们在导入模块的时候:import web1 这里的web1咱们不知道他是什么数据类型,他不是一个基本的数据类型
- 这里这个__import__(’web1‘)是以字符串的方式导入模块
- '''
- model_name = getattr(model,action)
- ret = model_name()
- print ret
- #输出结果:
- '''
- 请输入URL:web1/login1
- web1.login
- '''
咱们上面的代码是是用反射来实现的,想想一下如果用if..else来实现这个功能,如果我这个web1里有N种方法呢?或者我有N个模块呢?
如果用反射实现动态的导入模块和方法是不是就非常简单了?
有兴趣的可以实验一下用if..else来实现上面代码的功能对下!
在文件中的反射:
- import sys
- def function():
- print "hello world"
- current_model = sys.modules[__name__]
- if hasattr(current_model,'function'):
- renamefunc = getattr(current_model,'function')
- renamefunc()
- print sys.modules #一字典的形式显示当前脚本中的模块
- print __name__ # __name__ = __main__ 指定当前文件
- print sys.modules[__name__] # <module '__main__' from 'C:/Github/homework/test/fanshe.py'> 当前文件
更多请看:http://www.cnblogs.com/wupeiqi/articles/5017742.html
Python之路【第六篇】:面向对象编程相关的更多相关文章
- Python之路(第二十三篇) 面向对象初级:静态属性、静态方法、类方法
一.静态属性 静态属性相当于数据属性. 用@property语法糖装饰器将类的函数属性变成可以不用加括号直接的类似数据属性. 可以封装逻辑,让用户感觉是在调用一个普通的数据属性. 例子 class R ...
- Python之路(第二十七篇) 面向对象进阶:内置方法、描述符
一.__call__ 对象后面加括号,触发执行类下面的__call__方法. 创建对象时,对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()( ...
- Py修行路 python基础 (十六)面向对象编程的 继承 多态与多态性 封装
一.继承顺序: 多继承情况下,有两种方式:深度优先和广度优先 1.py3/py2 新式类的继承:在查找属性时遵循:广度优先 继承顺序是多条分支,按照从左往右的顺序,进行一步一步查找,一个分支走完会走另 ...
- Python之路(第六篇)Python全局变量与局部变量、函数多层嵌套、函数递归
一.局部变量与全局变量 1.在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量.全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序. 全局变量没有任何缩进,在任何位置都可 ...
- Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...
- 那些年被我坑过的Python——玄而又玄(第六章 面向对象编程基础)
面向对象编程: 面向对象顾名思义,就是把组织代码的粒度从函数级别抽象到对象级别,对象是通过类来生成的,类可以想象为模板或进本框架而对象是在原有模板或框架的基础上增加详细信息的实体,类,有分类.聚类的含 ...
- Python自动化 【第六篇】:Python基础-面向对象
目录: 面向过程VS面向对象 面向对象编程介绍 为什么要用面向对象进行开发 面向对象的特性:封装.继承.多态 面向过程 VS 面向对象 面向过程编程(Procedural Programming) ...
- Python开发【第六篇】:面向对象
configparser模块 configparser用于处理特定格式的文件,其本质是利用open来操作文件. 文件a.txt [section1] k1 = 123 k2:v2 [section ...
- Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") ret ...
- Python开发【第六篇】: 面向对象
内容概要 面向对象和面向过程 面向对象三大特征 面向对象的成员 类与类之间的关系 约束 type.issubclass.isinstance self.super.MRO 1. 面向对象和面向过程 0 ...
随机推荐
- css-控制元素中的字符超过规定的宽度影藏
代码如下: <div style="width:100px; white-space:nowrap;overflow:hidden;text-overflow:ellipsis; bo ...
- 安装centos虚拟机
启动虚拟机提示"无法连接虚拟设备ide1:0,主机上没有相对应的设备" 进入编辑虚拟机设置--选中硬盘--点高级--在 虚拟机设备节点中选ide0:0接行了.
- dede使用方法----实现英文版的搜索功能
搜索功能在网站中是最常见的一个功能了.我们在用dede做双语网站的时候,默认的会有中文版的搜索功能.但是怎么添加一个英文版的搜索功能.各位看官,方法如下: 1.复制plus目录下的serach.php ...
- AI,DM,ML,PR的区别与联系
数据挖掘和机器学习的区别和联系,周志华有一篇很好的论述<机器学习与数据挖掘>可以帮助大家理解.数据挖掘受到很多学科领域的影响,其中数据库.机器学习.统计学无疑影响最大.简言之,对数据挖掘而 ...
- bzoj4337: BJOI2015 树的同构
hash大法好 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...
- Java多线程与并发库高级应用-同步集合
ArrayBlockingQueue LinkedBlockingQueue 数组是连续的一片内存 链表是不连续的一片内存 传统方式下用Collections工具类提供的synchronizedCo ...
- JVM学习笔记:虚拟机性能监控
JDK中除了包含与开发密切相关的jar包外,还包含了很多非常实用的工具.在%JAVA_HOME%\bin\目录下面除了命令行工具外,还包括了几个强大的可视化工具.这些工具可以辅助我们开发.调试应用程序 ...
- Hadoop版本变迁
内容来自<Hadoop技术内幕:深入解析YARN架构设计与实现原理>第2章:http://book.51cto.com/art/201312/422022.htm Hadoop版本变迁 当 ...
- [Noi2016十连测第三场]线段树
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...
- List<List<String>>
package list; import java.util.ArrayList; import java.util.List; public class MyList { public static ...