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 ...
随机推荐
- Maven插件maven-surefire-plugin
插件官方文档:maven-surefire-plugin 1.surefire plugin的作用surefire 插件用来在maven构建生命周期的test phase执行一个应用的单元测试. 它会 ...
- WebApi服务Uri加密及验证的两种方式
最近的一个项目要求服务端与UI层分离,业务层以WebApi方式向外提供所有业务服务,服务在数据保密性方面提出了要求,主要包括: 1:客户端认证: 2:服务请求超时(默认5分钟): 3:服务Get请求的 ...
- eclipse中maven install和build,clean
eclipse插件,m2eclipse 1.maven install相当于maven原生的命令: mvn install 2.aven build是 m2eclipse这个插件自己创造的概念,需要你 ...
- Maven-搭建普通maven项目
点击Eclipse菜单栏File->New->Ohter->Maven得到如下图所示对话框: 选中Maven Project并点击Next,到下一个对话框(默认)继续点击Next得到 ...
- pyhthon --递归,装饰器
递归: 递归的概念很简单,如果函数包含了对其自身的调用,该函数就是递归.拗口一点的定义是,如果一个新的调用能在相同过程中较早的调用结束之前开始,那么该过程就是递归. """ ...
- UDP编程中client和server中使用recvfrom和sendto的区别
client中: sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,len); recvfrom(sfd,buf ...
- 面向对象_python
面向对象_python 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定 ...
- iOS9 支持http
在Info.plist中添加NSAppTransportSecurity类型Dictionary. 在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型 ...
- SQL select结果集和return的区别
IF EXISTS (SELECT 1 FRIN sys.objects where object_id=OBJECT_ID(N'[dbo].[testReturn_up]')AND type in ...
- springMVC的@ResponseBody、@RequestBody使用需要注意的地方
springMVC我觉得比struts2好的其中一个原因就是可以使用注解解析json数据,方便快捷.但是,即使如此,还是有需要注意的地方. 1.返回的地方设置@ResponseBody,请求的对象参数 ...