python面向對象編程(3)

類設計淺談

1.抽象類設計python

  • 抽象方法:在編寫class語句中,如有存在未定義或是未實現的或是@abstractmethod裝飾器修飾的
  • 抽象類:class中定義有抽象方法的類
## abs.py

## 第一種形式,僞抽象類,
class Super(object):
    def delegate(self):
        self.action()               ## action具體實現方法由子類定義z

    def action(self):
        raise NotImplementedError('action must be defined!')

class Sub(Super):
    def action(self):
        print("call sub action ...")

## 第二種形式
## py3.x
from abc import abstractmethod,ABCMeta

class Super(metaclass=ABCMeta):     ## 定義爲抽象類
    def delegate(self):
        self.action()

 @abstractmethod
    def action(self):
        pass

class Sub(Super):
    def action(self):
        print("call sub action ...")


## py2.x
from abc import abstractmethod,ABCMeta

class Super:                
    __metaclass__ = ABCMeta   ## 經過類屬性聲明
    def delegate(self):
        self.action()

 @abstractmethod
    def action(self):
        pass

class Sub(Super):
    def action(self):
        print("call sub action ...")

## 第二種形式的Super不可以進行實例化,第一種形式能夠進行實例化複製代碼

2.類的繼承與組合設計數據庫

  • 繼承是屬於"is a"的強依賴關係,擁有父類的一系列屬性和方法
  • 組合是屬於"has a"的弱依賴關係,也稱爲聚合,由各個組件組合而成共同完成一項任務目標
## task.py 
## 繼承
class Employee:
    def __init__(self, name, age):
        self.__name = name  ## 定義私有屬性,嚴格意義上是屬於僞屬性
        self.__age = age

    def get_name(self):
        return self.__name

    def get_age(self):
        return self.__age

    def work(self):
        print("employ work ...")


class Engineer(Employee):
    def work(self):
        print("engineer coding ...")


class ProductManager(Employee):
    def work(self):
        print("product manager desgin ...")


## 定義組合
class Customer:
    def __init__(self, name):
        self.__name = name

    def post_requirement(self):
        print("the %s post requirement ..." % self.__name)

class ProjectGroup:
    def __init__(self, engineer, manager):
        self.__engineer = engineer
        self.__manager = manager

    def build_dtrees(self, customer_name):
        customer = Customer(customer_name)
        customer.post_requirement()
        self.__manager.work()
        self.__engineer.work()

>>> engineer = Engineer("keithl",27)
>>> manager = ProductManager("keithl",27)
>>> pg = ProjectGroup(engineer,manager)
>>> pg.build_dtrees("xiaoming")

the xiaoming post requirement ...
product manager desgin ...
engineer coding ...複製代碼

3.類的委託(代理)python3.x

  • 對原有對象的方法進行加強,即在原有的方法基礎上,豐富方法的行爲
  • 重載__getattr__內置方法並使用getattr方法來回調被包裝類對象的屬性方法
## wrapper.py
class Wrapper:
    def __init__(self,object):
        self.__wrapper = object     ## 傳遞被包裝的對象

    def __getattr__(self,attrname):
        print("call wrapper for attr[%s] ...." % attrname)
        return getattr(self.__wrapper,attrname)

    def __str__(self):
        return str(self.__wrapper)

>>> engineer = Engineer("keithl",27)
>>> we = Wrapper(engineer)
>>> we.work("dtrees")
call wrapper for attr[work] ....
engineer review and coding ...複製代碼

4.僞屬性bash

  • 保證定義的類中的屬性(類屬性和實例屬性)名稱惟一,即便在同名屬性的狀況下也可以區分是屬於哪個類中定義的屬性
  • 在屬性的名稱前面添加__雙下劃線,後面不添加下劃線,py會將這類屬性轉換爲_className__attrName
  • 能夠當作是私有屬性,即對外暴露的屬性名稱再也不是定義的屬性名,而是_className__attrName
  • 使用僞屬性是保證惟一性,防止在多繼承過程當中不一樣的子類命名相同而衝突

定義Person類私有的name屬性app

## private.py
class Person:
    __template_name = "person instance template name"

    def __init__(self,name):    
        self.__name = name      ## __name 屬於Person類,

    def get_name(self):
        return self.__name

 @staticmethod
    def get_template_name():
        return Person.__template_name

>>> p = Person("keithl")
>>> print(p.get_name())
keithl

>>> print(p._Person__name)
keithl

>>> print(p.__name)
AttributeError: 'Person' object has no attribute '__name'

>>> print(dir(p))複製代碼

定義Person的子類各自的私有屬性函數

## sub.py
class Manager(Person):
    def __init__(self,name):
        self.__name = name      ## __name 屬於Manager類


class Engineer(Person):
    def __init__(self,name):
        self.__name = name      ## __name 屬於Engineer類

>>> m = Manager("manager")
>>> e = Engineer("engineer")

## 打印的結果以下圖所示
>>> print(dir(m)) 
>>> print(dir(e))複製代碼

5.方法的綁定與未綁定post

  • 未綁定對象的方法:不帶有self參數的方法,經過定義的類來調用函數並返回一個沒有綁定self的方法
  • 綁定對象的方法:帶有self參數的方法,即實例方法,經過實例對象調用函數並返回一個綁定self參數的方法
## fn.py
class BoundClass:
    def action(self):
        print("bound class action ....")

    """ python3.x未綁定self對象的方法均是類定義的函數,注意這個還不是屬於靜態方法和類方法 """
    def unbound(num):               ## work in py3.x,fail in py2.x
        print("the number is %d" % num)

>>> t = BoundClass()
>>> t.action()              ## action方法綁定實例對象self,能夠直接經過點號運算調用 

>>> m = BoundClass.action   ## m是沒有綁定實例對象self的方法
>>> m(t)                    ## 調用須要傳遞實例對象t複製代碼

6.對象工廠方法ui

  • 使用場景
    • 將代碼與動態配置對象構造器的實現細節分離
    • 能夠經過配置文件的內容在運行時動態建立實例對象
    • 工廠方法容許咱們使用未定義的類來避免硬編碼的方式進行類的導入和傳遞
## fa.py
def factory(aClass,*pargs,**kwargs):    ## aClass 具體是什麼類不清楚,只有在運行的時候才知道
    return aClass(pargs,kwargs)

## run-fa.py
""" 如今有一個配置文件setting.py,主要是用做配置數據庫的一系列參數,其中須要指定一個類是代表使用哪一種數據庫,如MySQL、Oracle... 假設在一個db.py定義了實現不一樣的數據庫對應的類模板 """

import setting.py                  ## 讀取配置文件

classargs = setting_db_config      ## 獲取實例化鏈接對象的數據庫配置參數,uri,port,username,password

classname = setting_db_class       ## 獲取類名稱的字符串

aClass = getattr(db,classname)     ## 從模塊中獲取類對象

connection = factory(aClass,classargs)  ## 傳遞參數建立類實例對象複製代碼
相關文章
相關標籤/搜索