1. 程式人生 > >Python之路【第五篇】:面向對象及相關

Python之路【第五篇】:面向對象及相關

訪問 遊戲 font raise 內置 無法 sys 接下來 print

面向對象基礎

基礎內容介紹詳見一下兩篇博文:

  • 面向對象初級篇
  • 面向對象進階篇

其他相關

一、isinstance(obj, cls)

檢查是否obj是否是類 cls 的對象

class Foo(object):
    pass

obj = Foo()

isinstance(obj, Foo)

二、issubclass(sub, super)

檢查sub類是否是 super 類的派生類

class Foo(object):
    pass

class Bar(Foo):
    pass

issubclass(Bar, Foo)

三、異常處理

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
View Code

2、異常種類

python中的異常種類非常多,每個異常專門用於處理某一項異常!!!

技術分享
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
更多異常 技術分享
dic = ["wupeiqi", alex]
try:
    dic[10]
except IndexError, e:
    print e
實例:IndexError 技術分享
dic = {k1:v1}
try:
    dic[k20]
except KeyError, e:
    print e
實例:KeyError 技術分享
s1 = hello
try:
    int(s1)
except ValueError, e:
    print e
實例:ValueError

對於上述實例,異常類只能用來處理指定的異常情況,如果非指定異常則無法處理。

# 未捕獲到異常,程序直接報錯

s1 = ‘hello‘
try:
    int(s1)
except IndexError,e:
    print e

所以,寫程序時需要考慮到try代碼塊中可能出現的任意異常,可以這樣寫:

s1 = ‘hello‘
try:
    int(s1)
except IndexError,e:
    print e
except KeyError,e:
    print e
except ValueError,e:
    print e

萬能異常 在python的異常中,有一個萬能異常:Exception,他可以捕獲任意異常,即:

s1 = ‘hello‘
try:
    int(s1)
except Exception,e:
    print e

接下來你可能要問了,既然有這個萬能異常,其他異常是不是就可以忽略了!

答:當然不是,對於特殊處理或提醒的異常需要先定義,最後定義Exception來確保程序正常運行。

s1 = ‘hello‘
try:
    int(s1)
except KeyError,e:
    print ‘鍵錯誤‘
except IndexError,e:
    print ‘索引錯誤‘
except Exception, e:
    print ‘錯誤‘

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()
View Code

答:有兩種方式,如下:

技術分享
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框架實例

結論:反射是通過字符串的形式操作對象相關的成員。一切事物都是對象!!!

技術分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import sys


def s1():
    print s1


def s2():
    print s2


this_module = sys.modules[__name__]

hasattr(this_module, s1)
getattr(this_module, s2)
反射當前模塊成員

類也是對象

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
home.py
#!/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)      # 創建波多多角色
View Code

面向對象場景二:

如:創建對數據庫操作的公共類

技術分享
# #### 定義類 ####

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()
View Code

實例:結合場景二實現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應用實例-單例模式

總結:單利模式存在的目的是保證當前內存中僅存在單個實例,避免內存浪費!!!

Python之路【第五篇】:面向對象及相關