1、面向对象三大特性:java
多态python
2、面向对象中的成员git
字段、方法属性编程
3、成员修饰符c#
4、特殊成员设计模式
__init__、__doc__、__call__、__setitem__、__getitem__、___delitem__、__str__、__all__cookie
5、面向对象其余session
--isinstance架构
--issubclassapp
--继承2.7
--应用:一、自定义类型(作一个有序的字典)
二、源码的扩展
6、设计模式之单例模式
7、异常处理
python里面定义一个函数,能够传入不一样类型的变量
def func(arg):
print(arg)
可是在c#/java中,arg这个参数必需要指定类型 '
若是在定义是指定了int类型数据,此时传入了str类型,就会报错了
在python中可传入任意类型这就是多态的一个表现
在java中若是想让java中支持多态,就要用继承来实现多态了
好比:
def func(int arg)
print(arg)
这个int能够是int和int的派生类
Class A: pass Class B(A): pass Class C(A): pass def func(A arg): print(arg) 此时arg前面就能够是A/B/C三种类型了。 由于此时你要是写进入一个C类型,你又传入一个A类。它先回判断是否是属于C类,不属于就往他的父类上面找。就找到了A。
字段、方法、属性
一、字段:
静态字段,普通字段
静态字段的好处class Province:
def __init__(self,name): self.name = name self.county = "中国" hn = Province("河南")
county = hn.county #普通字段用对象访问字段 hb = Province("河北") #这样每一个建立出一个对象中都保存着省份名字,和中国 #有不少省份的时候重复储存中国,耗费内存 若是使用静态字段 class Province: county = "中国" def __init__(self,name): self.name = name a = Province.county 访问静态字段用类名访问
#在python中静态字段也能够用对象访问,可是尽可能别用,若是哪一天改版,不让用了,你的代码就要重构。。。
print(a) 中国 #county保存在类中,不用建立对象也能够访问静态字段,由于静态字段是属于类 #这样你们共用这一个静态字段
访问规则:
普通字段,用对象访问
静态字段,用类访问,若是在你找不到类的时候万不得已了,用一下。
二、方法
普通方法,静态方法,类方法
类中的而函数增长一个self就是方法
普通方法:
普通方法属于类,是由对象调用执行
静态方法:
class Foo: def __init__(self,name): self.name = name self.age = 18 def show(self): print(self.name) def arg(self): print(self.age) #建立一个静态方法 #这个方法用不到这个类的对象,因此把self去掉,支持传参数 @staticmethod def f1(arg1): #参数任意,无关紧要 print(arg1) return True
#静态方法属于类,全部不用建立对象就能够调用 a = Foo.f1("静态方法") #执行, 类执行,也能够用对象执行,不到万不得已不要这么用。 print(a)
静态方法
True
其实静态方法和函数的功能是同样的,只不过它属于一个类,用处就是这个方法可能和这个类有某种关系,就是为了归类
类方法:
属于静态方法的特殊形式
class Foo: def __init__(self,name): self.name = name self.age = 18 def p1(self): print(self.name) @staticmethod #静态方法 def f1(arg1): print(arg1) return True @classmethod #类方法 def f2(cls):# cls是必须有的参数,在cls就像是函数中的self,cls就是类本身自己 print(cls) cls.f1("类方法直接调用静态方法") t1 = cls("类方法调用普通方法") t1.p1()#类方法调用普通方法
Foo.f2() #执行 由类执行,也能够对象执行,可是不到万不得已不要这么用。
<class '__main__.Foo'>
类方法直接调用静态方法
类方法调用普通方法
三、属性
具备方法的写做形式,具备字段的访问形式
属性本质就是方法,只是用访问字段的方式来执行方法
class pager: def __init__(self, all_count, pager_count): self.all_count = all_count self.pager_count = pager_count def all_pager(self): k1, k2 = divmod(self.all_count, self.pager_count) if k2 == 0: return k1 else: return k1 + 1 @property #加上这个装饰器在执行这个方法就不用加括号了 def all_pager1(self): k1, k2 = divmod(self.all_count, self.pager_count) if k2 == 0: return k1 else: return k1 + 1 a = pager(101, 10) print(a.all_count) #这样的写法是获取字典 pager_num = a.all_pager() #这样的写法是执行方法
pager_num1 = a.all_pager1 #这样写法就是用 获取字段的方式 执行方法
属性的扩展用法:
咱们能够以调取字段的写法 来执行 方法
哪先来看看字段均可以干什么
ret = a.all_count #这是读取字段中的值 这个写法对应属性是 pager_num1 = a.all_pager1
a.all_count = 105 #这是从新给字段赋值 这个写法对应属性是什么 ???
del a.all_count #这是删除字段 这个写法对应属性有是什么 ???
咱们来看看怎么用赋值的方法来操做
class pager: def __init__(self, all_count, pager_count): self.all_count = all_count self.pager_count = pager_count @property #加上这个装饰器在执行这个方法就不用加括号了 def all_pager1(self): k1, k2 = divmod(self.all_count, self.pager_count) if k2 == 0: return k1 else: return k1 + 1 @all_pager1.setter #将具备属性的方法名做为这个方法的装饰器 + setter, def all_pager1(self,value): #而且这个方法的名称和具备属性功能的方法名称相同 print(value)
a.all_pager1 = 106 #这样就能够将106这个值传入类中的all_pager1(value)这个方法中了
106
哪del 字段 这个写法在属性中怎么使用呢?class pager:
def __init__(self, all_count, pager_count): self.all_count = all_count self.pager_count = pager_count def all_pager(self):#普通方法 k1, k2 = divmod(self.all_count, self.pager_count) if k2 == 0: return k1 else: return k1 + 1 @property #属性 k1, k2 = divmod(self.all_count, self.pager_count) if k2 == 0: return k1 else: return k1 + 1def all_pager1(self): print("del all_pager1")
a = pager(101,10)
del a.all_pager1
属性的主流表达方式
################################# 定义 ####################################################
class Foo: def __init__(self,num): self.num = num def get_num(self): return self.num def set_num(self,value): print( self.num + value ) def del_num(self): print( self.num - 1) foo = property(fget=get_num,fset=set_num,fdel=del_num) ################################### 调用 ################################################# obj = Foo(5) result1 = obj.foo #去执行foo中的 fget对应的方法 print(result1) obj.foo = 5 #去执行foo中的 fset对应的方法 del obj.foo #去执行foo中的 fdel对应的方法
注意:Python WEB框架 Django 的视图中 request.POST 就是使用的静态字段的方式建立的属性
class WSGIRequest(http.HttpRequest): def __init__(self, environ): script_name = get_script_name(environ) path_info = get_path_info(environ) if not path_info: # Sometimes PATH_INFO exists, but is empty (e.g. accessing # the SCRIPT_NAME URL without a trailing slash). We really need to # operate as if they'd requested '/'. Not amazingly nice to force # the path like this, but should be harmless. path_info = '/' self.environ = environ self.path_info = path_info self.path = '%s/%s' % (script_name.rstrip('/'), path_info.lstrip('/')) self.META = environ self.META['PATH_INFO'] = path_info self.META['SCRIPT_NAME'] = script_name self.method = environ['REQUEST_METHOD'].upper() _, content_params = cgi.parse_header(environ.get('CONTENT_TYPE', '')) if 'charset' in content_params: try: codecs.lookup(content_params['charset']) except LookupError: pass else: self.encoding = content_params['charset'] self._post_parse_error = False try: content_length = int(environ.get('CONTENT_LENGTH')) except (ValueError, TypeError): content_length = 0 self._stream = LimitedStream(self.environ['wsgi.input'], content_length) self._read_started = False self.resolver_match = None def _get_scheme(self): return self.environ.get('wsgi.url_scheme') def _get_request(self): warnings.warn('`request.REQUEST` is deprecated, use `request.GET` or ' '`request.POST` instead.', RemovedInDjango19Warning, 2) if not hasattr(self, '_request'): self._request = datastructures.MergeDict(self.POST, self.GET) return self._request @cached_property def GET(self): # The WSGI spec says 'QUERY_STRING' may be absent. raw_query_string = get_bytes_from_wsgi(self.environ, 'QUERY_STRING', '') return http.QueryDict(raw_query_string, encoding=self._encoding) # ############### 看这里看这里 ############### def _get_post(self): if not hasattr(self, '_post'): self._load_post_and_files() return self._post # ############### 看这里看这里 ############### def _set_post(self, post): self._post = post @cached_property def COOKIES(self): raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '') return http.parse_cookie(raw_cookie) def _get_files(self): if not hasattr(self, '_files'): self._load_post_and_files() return self._files # ############### 看这里看这里 ############### POST = property(_get_post, _set_post) FILES = property(_get_files) REQUEST = property(_get_request) Django源码
因此,定义属性共有两种方式,分别是【装饰器】和【静态字段】,而【装饰器】方式针对经典类和新式类又有所不一样。
公有、私有
成员修饰符是对类成员设置权限的,成员:字段,方法,属性
公有:字段
在类的外部和内容部都能访问的字段,就是公有字段
私有:普通字段
哪继承能够访问吗?
class Foo: def __init__(self, name): self.__name = name def f1(self): print(self.__name) obj = Foo("han") print(obj.__name) obj.f1() class F1(Foo): def f1(self): print(self.__name) obj1 = F1("han") print(obj1.f1())
AttributeError: 'Foo' object has no attribute '__name'
继承也不能访问私有字段,只能本身类内部访问
私有:静态字段
class Foo: __CC = 123 def __init__(self, name): self.__name = name def f1(self): print(self.__name)
@classmethod #类方法调用本身
def f2(cls):
return cls.__CC
@staticmethod #静态方法调用
def f3(cls):
return cls.__CC
######### 调用私有静态字段 ######### ret = Foo.__CC
print(ret)
也是不能c从外部访问
只能从类的内部访问
ret = Foo.f2
ret2 = Foo.f3(Foo)
print(ret)
print(ret2)
123
123
私有:普通方法
class Foo: __CC = 123 def __init__(self, name): self.__name = name def __f1(self): print(self.__name) def t1(self,obj): obj.__f1()
obj = Foo("han")
obj.__f1() #这样是执行不了这个方法的
obj.t1(obj) 只能这样从内部调用
私有:静态方法
类方法:
class Foo: __CC = 123 def __init__(self, name): self.__name = name @classmethod def __f2(cls): return cls.__CC def t2(self): return self.__f2() obj = Foo("han") obj.__f2() #这样是执行不了的 ret = obj.t2() 这样内部调用t2,来间接的在内部执行__f2私有方法
print(ret)
123
静态方法
class Foo: __CC = 123 def __init__(self, name): self.__name = name @staticmethod def __f3(cls): (须要方法参数) #定义了一个私有方法 return cls.__CC def t3(self,cls): #内部定义了一个方法,访问上面的私有方法 return self.__f3(cls) obj = Foo("han") obj.t3(Foo) #也须要在内部调用
#python中也能够访问私有方法
############################ 定义 静态私有字段、私有字段、静态私有方法 #########################
class Foo: __CC = 123 #静态私有字段 def __init__(self, name): self.__name = name #静态字段 @staticmethod def __f3(cls): (须要方法参数) #定义了一个静态私有(类)方法 return cls.__CC def t3(self,cls): #内部定义了一个方法,访问上面的私有方法 return self.__f3(cls)
######################## 调用 ############################################################
#一、咱们想从外部直接访问私有方法
obj = Foo("han")
ret = obj._Foo__f3
print(ret)
#二、咱们想从外部直接访问私有静态字段
ret1 = Foo._Foo__CC(使用类访问静态私有字段)
ret2 = obj._Foo__CC(使用函数访问静态私有字段---不建议使用)
#三、咱们从外部直接访问私有字段
ret3 = obj._Foo__name
_Foo 就是后门
print(ret1,ret2,ret3)
写法:_类名__方法
特殊成员就是 __ XXX__,两边有下划线的。
一、__init__ : 构造方法,建立对象自动执行
obj = Foo() 此时对象刚出生,这时是自动执行__init__
二、__del__ : 析构方法,垃圾回收机制立刻要清除不用的对象时就会执行这个方法
等咱们不用这obj的时候。垃圾回收机制就会清除这个对象,在清除以前的一刹那,要是有__del__ 就会自动执行__del__.没有就直接清除。
三、__doc__ : 把类的注释保存在里面
四、__module__ & __class__
module:在建立一个对象时,想要知道这个对象在那个模块中
class : 这个对象的类名是什么
shuxing
<class 'shuxing.Foo'> #若是在相同的模块下就会显示 <class '__main__.Foo'>
五、__call__
class Foo: def __init__(self,arg1): self.name = arg1 def __call__(self,arg2): return arg2 obj = Foo("init") #类后面加() 是执行__init__ 方法 print(obj.name) ret = obj("call") #对象后面加() 是执行 __call__ 方法 print(ret)
init
call
class Foo: def __init__(self): print("init") def __call__(self): print("call") Foo()() #先执行构造方法,再执行call方法
init
call
#这个知道就能够了
六、__str__
打印一个建立好的对象,在没有定义str的时候 只会打印这个对象的内存地址
定之后就会打印这个方法下面return的内容
class Foo: def __init__(self,name): self.name = name def __str__(self): return self.name obj = Foo("han") print(obj), #不打印就用str(obj)来回去到return的值 han ret = str(obj) print(ret) han
七、__and__
用途:两个对象相加,就会执行前面对象中定义的 __add__ 方法
lass Foo: def __init__(self,name, age): self.name = name self.age = age def __add__(self, other): msg = "%s - %d" % (self.name, other.age) return msg obj1 = Foo("han",20) obj2 = Foo("shi",40) ret = obj1 + obj2 #self 则是 obj1 ,other 则是obj2 print(ret) han - 40
八、__dict__
用途:将对象中全部封装的字段取出来
#dict 本身不用写,对象中默认就有
class Foo: __CC = 123 BB = 000 def __init__(self,name, age): self.name = name self.age = age def __add__(self, other): msg = "%s - %d" % (self.name, other.age) return msg obj1 = Foo("han",20) obj2 = Foo("shi",40) ret1 = obj1.__dict__ ret2 = Foo.__dict__ print(ret1,"\n",ret2) {'age': 20, 'name': 'han'} {'__module__': '__main__', '__add__': <function Foo.__add__ at 0x0000000D688CF2F0>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'BB': 0, '_Foo__CC': 123, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__init__': <function Foo.__init__ at 0x0000000D688CF268>}
基本操做
a、__getitem__
提问:
dic = {"k1":123} #建立dic字段 dic = dict("k1" = 123) d1 = dic["k1"] #获取k1的value dic["k1"] = 345 #给k1的value 改值
del dic["k1"] #删除
在一个对象后面加() obj()执行call方法
那么在对象后面加[] obj[] 是什么鬼?这个语法究竟是执行什么方法呢?
obj[] 这么写就是执行 __gititem__方法
lass Foo: __CC = 123 BB = 000 def __init__(self,name, age): self.name = name self.age = age def __getitem__(self, item=None): if not item: print("getitem") else: print(item) obj = Foo("han",123) obj["ab"] getitem
语法:在执行obj[]语法的时候就会执行 __getitem__这个方法,而后会把【】中的值传进item中
b、__setitem__
obj[] = 123 这么写就是执行 __setitem__方法
class Foo: __CC = 123 BB = 000 def __init__(self,name, age): self.name = name self.age = age def __setitem__(self, key, value): print(key,value) obj = Foo("han",123) obj["ab"] = 444 ab 444
c、__delitem__
del obj[]这么写就是执行__delitem__方法
class Foo: __CC = 123 BB = 000 def __init__(self,name, age): self.name = name self.age = age def __delitem__(self, key): print(key,"del") obj = Foo("han",123) del obj["ab"] ab del
用处:自定义session框架时会使用
===================================================================
切片方式操做
obj[1:2] 这样咱们怎么操做?
class Foo: __CC = 123 BB = 000 def __init__(self,name, age): self.name = name self.age = age def __getitem__(self, item): print(type(item)) obj = Foo("han",123) ret = obj[1:5] <class 'slice'>
__getitem__
obj[1:2] 仍是用的 getitem 方法
因此obj[1:2]传入的类型是slice
那咱们怎么操做这样传入的数据哪?
python3中就这样作的
obj[1:5:4] = [11,22,33,44]
__setitem__
obj[1:5:4] = [11,22,33,44] 也是用的 __setitem__方法
del obj[1:5:4]
__delitem__
del obj[1:5:4]也是用的 __deltiem__方法
十、__iter__
让对象的返回值迭代起来
默认返回的对象是不可迭代的
class Foo: def __init__(self,num): self.num = num def test(self): return self.num obj = Foo([1,2,3,4]) for i in obj: print(i) TypeError: 'Foo' object is not iterable 默认对象是不能迭代的
使用__iter__ 方法后,迭代这个对象时,就会默认执行类中的__iter__方法。
class Foo: def __init__(self,num): self.num = num def test(self): return self.num def __iter__(self): return iter(self.num) obj = Foo([1,2,3,4]) for i in obj: print(i) 1 2 3 4
使用生成器来作一个可迭代对象
class Foo: def __init__(self,num): self.num = num def test(self): return self.num def __iter__(self): for i in self.num: yield i 1 2 3 4
对象被迭代的步骤,一、将对象放到for中,二、找对象中的__iter__方法,三、__iter__中返回值能够被迭代。 ''
十一、 __all__
这个特殊方式是在被倒入的时候生效的
好比咱们有2个module 一个是 test1,一个是test2
test2 要倒入test1 中的类咱们能够有几种方式
1. import test1.Foo1 ... ...
2.import test1
3.from test1 import Foo1
4.from test1 import *
目前测试 __all__ 是在最后一种方式倒入的时候生效
若是咱们在test1中定义了 __all__ , from test1 import * 时只会找到再__all__ 里面定义的类作倒入
test1.py
__all__ = ["Foo1", "Foo2"] class Foo1: def f1(self): print("foo1") class Foo2: def f1(self): print("foo2") class Foo3: def f1(self): print("foo3") class Foo4: def f1(self): print("foo4")
test2.py
from test1 import * #若是这样倒入就只能找到Foo1,和Foo2,由于Foo3和Foo4没有在test1的__all__列表中 a = Foo1() a.f1() b = Foo2() b.f1() c = Foo3() c.f1() d = Foo4() d.f1()
一、isinstence
判断这个对象是否是某个类的子类
class Foo: def __init__(self,num): self.num = num def test(self): return self.num def __iter__(self): for i in self.num: yield i obj = Foo([1,2,3,4]) ret = isinstance(obj,Foo) print(ret) True
补充:Foo,能够是bar的类型,也能够是bar的父类。
class Bar: pass class Foo(Bar): def __init__(self,num): self.num = num def test(self): return self.num def __iter__(self): for i in self.num: yield i obj = Foo([1,2,3,4]) ret = isinstance(obj,Bar) print(ret)
二、issubclass
查看一个类是否是另外一个类的子类
class Foo: def __init__(self,num): self.num = num def test(self): return self.num def __iter__(self): for i in self.num: yield i class Bar(Foo): pass obj = Foo([1,2,3,4]) ret = issubclass(Bar,Foo) print(ret) True
三、super()
执行父类中相同名称的方法
class C1: def f1(self): print("c1.f1") class C2(C1): def f1(self): print("c2.f1") obj = C2() obj.f1() #由于子类和父类同时都有一个f1方法,因此优先执行子类C2中的函数
此时我要是想主动的执行如下父类C1的函数怎么办?
class C1: def f1(self): print("c1.f1") return 123 class C2(C1): def f1(self): a = super(C2,self).f1() #这一步就是主动的先执行父类中的f1方法,并能够获取f1方法中的返回值 print(a) obj = C2() obj.f1() c1.f1 #先执行C1中的f1方法 123 #再执行C2中的f1方法
私用场景:假如使用了大型的第三方架构,若是某一个功能不是你想要的,想要增长一点功能,若是你修改源码,很差,就本身写一个类,而后继承原来的源码使用super就能够
#另外一种非主流的写法 class C1: def f1(self): print("c1,f1") return 123 class C2(C1): def f1(self): C1.f1(self) #执行C1这个类的f1方法,可是要讲本身的self传进去。 #这样也能够主动执行父类的f1方法
应用
/banchend/commons.py 源码
class Foo: def f1(self): print('Foo.f1') #源码的代码,咱们要在不改动源码的前提下在 print(‘Foo.f1’)的上面和下面分别输出句话
from settings import ClassName from settings import Path def execute(): module = __import__(Path,fromlist=True) if hasattr(module,ClassName): cls = getattr(module,ClassName) obj = cls() obj.f1() else: print("no module") if __name__ == '__main__': execute()
from backend import commons class New_Foo(commons.Foo): #新的类继承源码类 def f1(self): print("befor") #上面多输出一行 super(New_Foo,self).f1()#使用super来强制调用父类f1方法 print("after") #下面多输出一行
Path = "NewFoo" #这个就对应着反射查找的位置 ClassName = "New_Foo" #这个对应着新的类
四、制做一个有序的字典
思路,在字典的基础上进行操做,字典没有提供有序的功能,我就提供这个没有的功能
class MyDict(dict): def __init__(self): self.li = [] #个人init方法,可是咱们又还要使用dict的init方法 super(MyDict,self).__init__()#这样就保留下来了源码的init方法 def __setitem__(self, key, value): self.li.append(key) #将key添加到本身维护的列表中 , 可是咱们key,value没有传入到字典中去 super(MyDict, self).__setitem__(key,value) #那就再使用父类的setitem方法来保存key,value def __delitem__(self, key): #删除字典用某个元素 num = self.li.index(key) #从列表中找到key的位置 del self.li[num] #从列表中删除 super(MyDict, self).__delitem__(key) #还要从字典中删除,那就交给父类的delitem把 def __str__(self): #orint的时候展现 new_list = [] for k in self.li: #循环遍历自定义的key列表 v = self.get(k) #用继承过来的get功能获取到对应的velue new_list.append("'%s':%s" % (k, v)) #将key和velue 按照 key:velue的方式保存到新的空列表中 temp_str = ",".join(new_list) #以,分割转换成为字符串 temp = "{" + temp_str + "}" #先后各加上大括号 return temp #输出
执行
###### 生成对象 ############## from My_Dict import MyDict obj = MyDict() ###### 赋值 ################# #此时使用了__setitem__ 功能 obj["k1"] = [1,2,3] obj["k2"] = [2,3,4] obj["k3"] = [4,5,6] ####### 删除 ################ #此时使用了__delitem__ 功能 del obj["k1"] ####### 输出 ################ #此时使用了__str__功能 print(obj,type(obj))
表示只有一个实例,一个对象:
用来建立单个实例:
class C1: instance = None #静态字段 def __init__(self,name): self.name = name def __str__(self): return self.name @classmethod def get_inistance(cls): #建立个类方法 if cls.instance: #若是此时的静态字段为真 return cls.instance #返回这个静态字段 else: #不为真,也就是第一次访问 obj = cls("han") #对这个类建立一个对象 cls.instance = obj #而后赋值给静态字段 return obj #而后返回这个对象 obj = C1.get_inistance() obj1 = C1.get_inistance() print(id(obj)) print(id(obj1)) 949172666552 949172666552
第一次建立对象,将对象赋值给静态字段,再次要建立对象时会去看看静态字段里面,有值则会把以前在类中生成的obj返回出来。
经过静态字段保存对象状态,下次再来时直接返回。
在编程过程当中为了增长友好性,在程序出现bug时通常不会将错误信息显示给用户,而是现实一个提示的页面,通俗来讲就是不让用户看见大黄页!!!
try: pass 若是准确就执行try中代码 except Exception,ex: #若是有错误就执行这里面的代码 pass
一、普通异常处理
while True: num1 = input('num1: ') num2 = input("num2: ") num1 = int(num1) num2 = int(num2) ret = num1 + num2 #若是num1 或 num2 不为 整数类型就会报错 ValueError: invalid literal for int() with base 10: 'ads' #而后程序就终止了
while True: num1 = input('num1: ') num2 = input("num2: ") try: #若是正常,则执行try里的代码 num1 = int(num1) num2 = int(num2) ret = num1 + num2 except Exception as ex: #若是不正常,报错被Exception截获,并建立ex对象,而后打印ex。这样就不会由于报错,致使程序终止了。 print(ex)
二、多种异常种类
1 AttributeError 试图访问一个对象没有的树形,好比foo.x,可是foo没有属性x 2 IOError 输入/输出异常;基本上是没法打开文件 3 ImportError 没法引入模块或包;基本上是路径问题或名称错误 4 IndentationError 语法错误(的子类) ;代码没有正确对齐 5 IndexError 下标索引超出序列边界,好比当x只有三个元素,却试图访问x[5] 6 KeyError 试图访问字典里不存在的键 7 KeyboardInterrupt Ctrl+C被按下 8 NameError 使用一个还未被赋予对象的变量 9 SyntaxError Python代码非法,代码不能编译(我的认为这是语法错误,写错了) 10 TypeError 传入对象类型与要求的不符合 11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是因为另有一个同名的全局变量, 12 致使你觉得正在访问它 13 ValueError 传入一个调用者不指望的值,即便值的类型是正确的
1 ArithmeticError 2 AssertionError 3 AttributeError 4 BaseException 5 BufferError 6 BytesWarning 7 DeprecationWarning 8 EnvironmentError 9 EOFError 10 Exception 11 FloatingPointError 12 FutureWarning 13 GeneratorExit 14 ImportError 15 ImportWarning 16 IndentationError 17 IndexError 18 IOError 19 KeyboardInterrupt 20 KeyError 21 LookupError 22 MemoryError 23 NameError 24 NotImplementedError 25 OSError 26 OverflowError 27 PendingDeprecationWarning 28 ReferenceError 29 RuntimeError 30 RuntimeWarning 31 StandardError 32 StopIteration 33 SyntaxError 34 SyntaxWarning 35 SystemError 36 SystemExit 37 TabError 38 TypeError 39 UnboundLocalError 40 UnicodeDecodeError 41 UnicodeEncodeError 42 UnicodeError 43 UnicodeTranslateError 44 UnicodeWarning 45 UserWarning 46 ValueError 47 Warning 48 ZeroDivisionError
实例:
dic = ["han","xu"] #一共就2个元素 try: dic[10] #这里却获取第10个元素 except IndexError as ex: #indexerror就是捕获索引错误的 print(ex)
dic = {'k1':'v1'} try: dic['k20'] except KeyError as ex: print(ex)
s1 = 'hello' try: int(s1) except ValueError as ex: print(ex)
捕获想要的异常操做
while True: num1 = input("num1 ") num2 = input("num2 ") try: num1 = int(num1) num2 = int(num2) ret = num1 + num2 print(ret) except ValueError as ex: #若是想对某种错误进行关注,就能够这样有针对性的进行错误捕获 print(ex) #这里就能够用日志来记录到文件中 except IndexError as ex: print(ex) except Exception as ex: #除了这两种错误,我就能够把其余的进行笼统的捕获 print(ex) #这里的错误就能够显示到屏幕上来。
看到上面的例子咱们就知道了,为了程序的正常运行咱们会在最下面用一个Exception这个万能的异常,上面是想捕捉的这些异常。
三、完整异常处理:
while True: num1 = input("num1 ") num2 = input("num2 ") try: num1 = int(num1) #正常的业务逻辑代码 num2 = int(num2) ret = num1 + num2 print(ret) except ValueError as ex: #若是想对某种错误进行关注,就能够这样有针对性的进行错误捕获 print(ex) #这里就能够用日志来记录到文件中 except IndexError as ex: print(ex) except Exception as ex: #除了这两种错误,我就能够把其余的进行笼统的捕获 print(ex) #这里的错误就能够显示到屏幕上来。 else: print("没有错就执行") finally: print("有没有错都执行")
四、主动触发异常
while True: num1 = input("num1 ") num2 = input("num2 ") try: raise Exception("错误") #这里能够随意定义异常的类型,定义什么类型的异常,下面就能够接受什么样的类型 print(123) #由于上面主动执行了异常,因此这里就不执行了 except ValueError as ex: #若是想对某种错误进行关注,就能够这样有针对性的进行错误捕获 print(ex,"value") except IndexError as ex: print(ex,"index") except Exception as ex: #上面raise的异常就被这里接受了 print(ex,"except")
五、断言
assert
使用方法
while True: num1 = input("num1 ") num2 = input("num2 ") try: assert int(num1) == int(num2) #若是这两个值相等,则执行print(123) print(123) #若是不相等,就直接报错 except AssertionError as ex: print(ex, "assert") else: print("没有错就执行") finally: print("有没有错都执行")
若是有个对象是启动某个程序的,想启动某些程序须要知足的条件: 当前这个程序应该是中止状态, 这个程序有个方法 class process: def status(self): ret = 查看当前程序的状态 (True/False) return ret def start(self) try: assert self.status() == False #在这里就至关于判断了状态,若是等于False,就知足启动条件,不然就报错了 则执行启动程序 except AssertionError as ex: #这里接受报错 print(ex, "assert") #并打印
from multiprocessing import pool b = pool.Pool b.join() def join(self): util.debug('joining pool') assert self._state in (CLOSE, TERMINATE) #能知足我这个条件就往下执行,不然就抛出个异常 self._worker_handler.join() self._task_handler.join() self._result_handler.join() for p in self._pool: p.join()