轉自博客:http://www.cnblogs.com/wupeiqi/articles/5040823.html
異常處理
1、異常基礎
在編程過程中爲了增加友好性,在程序出現bug時一般不會將錯誤信息顯示給用戶,而是現實一個提示的頁面,通俗來說就是不讓用戶看見大黃頁!!!
try: pass except Exception,ex: pass
例: while True: num1 = raw_input('num1:') num2 = raw_input('num2:') try: num1 = int(num1) num2 = int(num2) result = num1 + num2 except Exception, e: print '出現異常,信息如下:' print e
常見異常 AttributeError 試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x IOError 輸入/輸出異常;基本上是無法打開文件 ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤 IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊 IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5] KeyError 試圖訪問字典裏不存在的鍵 KeyboardInterrupt Ctrl+C被按下 NameError 使用一個還未被賦予對象的變量 SyntaxError Python代碼非法,代碼不能編譯(個人認爲這是語法錯誤,寫錯了) TypeError 傳入對象類型與要求的不符合 UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量, 導致你以爲正在訪問它 ValueError 傳入一個調用者不期望的值,即使值的類型是正確的
萬能異常 在python的異常中,有一個萬能異常:Exception,他可以捕獲任意異常,即: s1 = 'hello' try: int(s1) except Exception,e: print e
3、異常其他結構 try: # 主代碼塊 pass except KeyError,e: # 異常時,執行該塊 pass else: # 主代碼塊執行完,執行該塊 pass finally: # 無論異常與否,最終執行該塊 pass
4、主動觸發異常
try
:
raise
Exception(
'錯誤了。。。'
)
except
Exception,e:
print
e
5、自定義異常
class
WupeiqiException(Exception):
def
__init__(
self
, msg):
self
.message
=
msg
def
__str__(
self
):
return
self
.message
try
:
raise
WupeiqiException(
'我的異常'
)
except
WupeiqiException,e:
print
e
6、斷言
# assert 條件
assert
1
=
=
1
assert
1
=
=
2
四、反射
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'
)
詳細解析:
當我們要訪問一個對象的成員時,應該是這樣操作:
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
'alex'
def
func(
self
):
return
'func'
obj
=
Foo()
# 訪問字段
obj.name
# 執行方法
obj.func()
那麼問題來了?
a、上述訪問對象成員的 name 和 func 是什麼?
答:是變量名
b、obj.xxx 是什麼意思?
答:obj.xxx 表示去obj中或類中尋找變量名 xxx,並獲取對應內存地址中的內容。
c、需求:請使用其他方式獲取obj對象中的name變量指向內存中的值 “alex”
class Foo(object): def __init__(self): self.name = 'alex' # 不允許使用 obj.name obj = Foo()
答:有兩種方式,如下:
class Foo(object): def __init__(self): self.name = 'alex' def func(self): return 'func' # 不允許使用 obj.name obj = Foo() print obj.__dict__['name'] 方式一
class Foo(object): def __init__(self): self.name = 'alex' def func(self): return 'func' # 不允許使用 obj.name obj = Foo() print getattr(obj, 'name') 方式二
d、比較三種訪問方式
obj.name
obj.__dict__['name']
getattr(obj, 'name')
答:第一種和其他種比,...
第二種和第三種比,...
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server class Handler(object): def index(self): return 'index' def news(self): return 'news' def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] temp = url.split('/')[1] obj = Handler() is_exist = hasattr(obj, temp) if is_exist: func = getattr(obj, temp) ret = func() return ret else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8001, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever() Web框架實例
結論:反射是通過字符串的形式操作對象相關的成員。一切事物都是對象!!!
類也是對象
class
Foo(
object
):
staticField
=
"old boy"
def
__init__(
self
):
self
.name
=
'wupeiqi'
def
func(
self
):
return
'func'
@staticmethod
def
bar():
return
'bar'
print
getattr
(Foo,
'staticField'
)
print
getattr
(Foo,
'func'
)
print
getattr
(Foo,
'bar'
)
模塊也是對象
#!/usr/bin/env python# #-*- coding:utf-8 -*- def dev(): return 'dev'
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
程序目錄:
home.py
index.py
當前文件:
index.py
"""
import
home as obj
#obj.dev()
func
=
getattr
(obj,
'dev'
)
func()
一、單例模式
單例,顧名思義單個實例。
學習單例之前,首先來回顧下面向對象的內容:
python的面向對象由兩個非常重要的兩個“東西”組成:類、實例
面向對象場景一:
如:創建三個遊戲人物,分別是:
蒼井井,女,18,初始戰鬥力1000
東尼木木,男,20,初始戰鬥力1800
波多多,女,19,初始戰鬥力2500
# ##################### 定義類 ##################### class Person: def __init__(self, na, gen, age, fig): self.name = na self.gender = gen self.age = age self.fight =fig def grassland(self): """註釋:草叢戰鬥,消耗200戰鬥力""" self.fight = self.fight - 200 # ##################### 創建實例 ##################### cang = Person('蒼井井', '女', 18, 1000) # 創建蒼井井角色 dong = Person('東尼木木', '男', 20, 1800) # 創建東尼木木角色 bo = Person('波多多', '女', 19, 2500) # 創建波多多角色
面向對象場景二:
如:創建對數據庫操作的公共類
增
刪
改
查
# #### 定義類 #### class DbHelper(object): def __init__(self): self.hostname = '1.1.1.1' self.port = 3306 self.password = 'pwd' self.username = 'root' def fetch(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def create(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def remove(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def modify(self): # 連接數據庫 # 拼接sql語句 # 操作 pass # #### 操作類 #### db = DbHelper() db.create()
實例:結合場景二實現Web應用程序
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server class DbHelper(object): def __init__(self): self.hostname = '1.1.1.1' self.port = 3306 self.password = 'pwd' self.username = 'root' def fetch(self): # 連接數據庫 # 拼接sql語句 # 操作 return 'fetch' def create(self): # 連接數據庫 # 拼接sql語句 # 操作 return 'create' def remove(self): # 連接數據庫 # 拼接sql語句 # 操作 return 'remove' def modify(self): # 連接數據庫 # 拼接sql語句 # 操作 return 'modify' class Handler(object): def index(self): # 創建對象 db = DbHelper() db.fetch() return 'index' def news(self): return 'news' def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] temp = url.split('/')[1] obj = Handler() is_exist = hasattr(obj, temp) if is_exist: func = getattr(obj, temp) ret = func() return ret else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8001, RunServer) print "Serving HTTP on port 8001..." httpd.serve_forever() Web應用程序實例
對於上述實例,每個請求到來,都需要在內存裏創建一個實例,再通過該實例執行指定的方法。
那麼問題來了...如果併發量大的話,內存裏就會存在非常多功能上一模一樣的對象。存在這些對象肯定會消耗內存,對於這些功能相同的對象可以在內存中僅創建一個,需要時都去調用,也是極好的!!!
鐺鐺 鐺鐺 鐺鐺鐺鐺鐺,單例模式出馬,單例模式用來保證內存中僅存在一個實例!!!
通過面向對象的特性,構造出單例模式:
# ########### 單例類定義 ###########
class
Foo(
object
):
__instance
=
None
@staticmethod
def
singleton():
if
Foo.__instance:
return
Foo.__instance
else
:
Foo.__instance
=
Foo()
return
Foo.__instance
# ########### 獲取實例 ###########
obj
=
Foo.singleton()
對於Python單例模式,創建對象時不能再直接使用:obj = Foo(),而應該調用特殊的方法:obj = Foo.singleton()
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server # ########### 單例類定義 ########### class DbHelper(object): __instance = None def __init__(self): self.hostname = '1.1.1.1' self.port = 3306 self.password = 'pwd' self.username = 'root' @staticmethod def singleton(): if DbHelper.__instance: return DbHelper.__instance else: DbHelper.__instance = DbHelper() return DbHelper.__instance def fetch(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def create(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def remove(self): # 連接數據庫 # 拼接sql語句 # 操作 pass def modify(self): # 連接數據庫 # 拼接sql語句 # 操作 pass class Handler(object): def index(self): obj = DbHelper.singleton() print id(single) obj.create() return 'index' def news(self): return 'news' def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] temp = url.split('/')[1] obj = Handler() is_exist = hasattr(obj, temp) if is_exist: func = getattr(obj, temp) ret = func() return ret else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8001, RunServer) print "Serving HTTP on port 8001..." httpd.serve_forever() Web應用實例-單例模式