類和對象(實例)

  1. 先將對象分類
  2. 歸納出共同特征,構(gòu)建基類
  3. 構(gòu)建子類,描述其不同狀態(tài)(變量)和行為
  4. 創(chuàng)建類的實例,表示某個對象
  5. 對象通過行為觸發(fā)或與其他對象交互,來實現(xiàn)具體功能
    如此一來,既節(jié)約了內(nèi)存空間,又少寫了代碼。(抽象是為了偷懶,偷懶是計算機前進的動力之一)
  6. 存活的實例對象都有 “唯一“ 的ID值,可使用內(nèi)置函數(shù)id()查看。(id函數(shù)用來獲得對象的內(nèi)存地址,并且,該ID值只能保證在某個時間段內(nèi)該存活對象唯一,所以,該ID不適合作為全局身份標識)
  7. type()函數(shù)用來返回實例所屬類型,不會考慮繼承關(guān)系
  8. isinstance()函數(shù)判斷實例是否屬于特定類型,會考慮繼承關(guān)系

面向?qū)ο蟮娜筇匦裕?/h1>
  1. 封裝
  2. 繼承
  3. 多態(tài)

經(jīng)典類和新式類

  • 當類是經(jīng)典類時,多繼承情況下,會按照深度優(yōu)先方式查找
  • 當類是新式類時,多繼承情況下,會按照廣度優(yōu)先方式查找
  1. 如果該類或其父類繼承了object類,那么該類便是新式類,否則便是經(jīng)典類(新式類是推薦寫法,包含更多的功能)

類和對象在內(nèi)存中的保存方式

  • 類及類中的屬性和方法,在內(nèi)存中只保存一份
  • 每個對象都需要在內(nèi)存中保存一份(只保存對象的屬性,及指向類的類對象指針)。因此,在對象執(zhí)行方法時,會先通過類對象指針找到類中對應(yīng)的方法,將對象當作參數(shù)傳給方法的第一個參數(shù)self

類的成員

  • 類的成員可以分為三大類:字段,方法和屬性
  • 字段
    1. 普通字段(所有成員中,只有普通字段的內(nèi)容是保存在對象中的,其他成員均保存在類中,在內(nèi)存中只創(chuàng)建一份)
    2. 靜態(tài)字段
class Province:

    # 靜態(tài)字段
    country = '中國'

    def __init__(self, name):

        # 普通字段
        self.name = name

# 直接訪問普通字段
obj = Province('河北省')
print obj.name

# 直接訪問靜態(tài)字段
Province.country
  • 方法
    1. 普通方法
    2. 類方法
    3. 靜態(tài)方法
class Foo:
 
    def __init__(self, name):
        self.name = name
 
    def ord_func(self):
        """ 定義普通方法,至少有一個self參數(shù) """
 
        # print self.name
        print '普通方法'
 
    @classmethod
    def class_func(cls):
        """ 定義類方法,至少有一個cls參數(shù) """
 
        print '類方法'
 
    @staticmethod
    def static_func():
        """ 定義靜態(tài)方法 ,無默認參數(shù)"""
 
        print '靜態(tài)方法'
 
# 調(diào)用普通方法(自動將調(diào)用該方法的對象賦值給self)
f = Foo()
f.ord_func()
 
# 調(diào)用類方法(自動將調(diào)用該方法的類復(fù)制給cls)
Foo.class_func() # 推薦
f.class_func()
 
# 調(diào)用靜態(tài)方法(由類調(diào)用)
Foo.static_func() # 推薦
f.static_func
  • 屬性
    1. 普通屬性(屬性存在意義是:訪問屬性時可以制造出和訪問字段完全相同的假象)(屬性由方法變種而來,如果Python中沒有屬性,方法完全可以代替其功能)
# ############### 定義 ###############
class Pager:

    def __init__(self, current_page):
        # 用戶當前請求的頁碼(第一頁、第二頁...)
        self.current_page = current_page
        # 每頁默認顯示10條數(shù)據(jù)
        self.per_items = 10 

    @property
    def start(self):
        val = (self.current_page - 1) * self.per_items
        return val

    @property
    def end(self):
        val = self.current_page * self.per_items
        return val

# ############### 調(diào)用 ###############

p = Pager(1)
p.start # 就是起始值,即:m
p.end # 就是結(jié)束值,即:n

# 定義時,在普通方法的基礎(chǔ)上添加 @property 裝飾器;
# 定義時,屬性僅有一個self參數(shù)
# 調(diào)用時,無需括號,自動執(zhí)行屬性,并獲取屬性的返回值
# 方法:foo_obj.func()
# 屬性:foo_obj.prop
  1. 定義屬性的兩種方式
  • 裝飾器定義(新式類有三種屬性定義裝飾器,經(jīng)典類只有@property一種)
# ############### 定義 ###############
class Goods(object):
 
    @property
    def price(self):
        print '@property'
 
    @price.setter
    def price(self, value):
        print '@price.setter'
 
    @price.deleter
    def price(self):
        print '@price.deleter'
 
# ############### 調(diào)用 ###############
obj = Goods()
 
obj.price          # 自動執(zhí)行 @property 修飾的 price 方法,并獲取方法的返回值
 
obj.price = 123    # 自動執(zhí)行 @price.setter 修飾的 price 方法,并將  123 賦值給方法的參數(shù)
 
del obj.price      # 自動執(zhí)行 @price.deleter 修飾的 price 方法

由于新式類中具有三種訪問方式,我們可以根據(jù)他們幾個屬性的訪問特點,分別將三個方法定義為對同一個屬性:獲取、修改、刪除

class Goods(object):
 
    def __init__(self):
        # 原價
        self.original_price = 100
        # 折扣
        self.discount = 0.8
 
    @property
    def price(self):
        # 實際價格 = 原價 * 折扣
        new_price = self.original_price * self.discount
        return new_price
 
    @price.setter
    def price(self, value):
        self.original_price = value
 
    @price.deltter
    def price(self, value):
        del self.original_price # del刪除的是變量,解除變量和數(shù)據(jù)的引用,而不是刪除數(shù)據(jù)
 
obj = Goods()
obj.price         # 獲取商品價格
obj.price = 200   # 修改商品原價
del obj.price     # 刪除商品原價
  • 靜態(tài)字段定義(當使用靜態(tài)字段的方式創(chuàng)建屬性時,經(jīng)典類和新式類無區(qū)別)
class Foo:
 
    def get_bar(self):
        return 'wupeiqi'
 
    BAR = property(get_bar)
 
obj = Foo()
reuslt = obj.BAR        # 自動調(diào)用get_bar方法,并獲取方法的返回值
print reuslt

property的構(gòu)造方法中有個四個參數(shù)
第一個參數(shù)是方法名,調(diào)用 對象.屬性 時自動觸發(fā)執(zhí)行方法
第二個參數(shù)是方法名,調(diào)用 對象.屬性 = XXX 時自動觸發(fā)執(zhí)行方法
第三個參數(shù)是方法名,調(diào)用 del 對象.屬性 時自動觸發(fā)執(zhí)行方法
第四個參數(shù)是字符串,調(diào)用 對象.屬性.doc ,此參數(shù)是該屬性的描述信息

class Foo:
 
    def get_bar(self):
        return 'wupeiqi'
 
    # *必須兩個參數(shù)
    def set_bar(self, value): 
        return 'set value' + value
 
    def del_bar(self):
        return 'wupeiqi'
 
    BAR = property(get_bar, set_bar, del_bar, 'description...')
 
obj = Foo()
 
obj.BAR              # 自動調(diào)用第一個參數(shù)中定義的方法:get_bar
obj.BAR = "alex"     # 自動調(diào)用第二個參數(shù)中定義的方法:set_bar方法,并將“alex”當作參數(shù)傳入
del Foo.BAR          # 自動調(diào)用第三個參數(shù)中定義的方法:del_bar方法
obj.BAE.__doc__      # 自動獲取第四個參數(shù)中設(shè)置的值:description...

由于靜態(tài)字段方式創(chuàng)建屬性具有三種訪問方式,我們可以根據(jù)他們幾個屬性的訪問特點,分別將三個方法定義為對同一個屬性:獲取、修改、刪除

class Goods(object):
 
    def __init__(self):
        # 原價
        self.original_price = 100
        # 折扣
        self.discount = 0.8
 
    def get_price(self):
        # 實際價格 = 原價 * 折扣
        new_price = self.original_price * self.discount
        return new_price
 
    def set_price(self, value):
        self.original_price = value
 
    def del_price(self, value):
        del self.original_price
 
    PRICE = property(get_price, set_price, del_price, '價格屬性描述...')
 
obj = Goods()
obj.PRICE         # 獲取商品價格
obj.PRICE = 200   # 修改商品原價
del obj.PRICE     # 刪除商品原價

類成員的修飾符

  • 公有成員,在任何地方都能訪問
  • 私有成員,只有在類的內(nèi)部才能訪問
    私有成員和公有成員的定義不同:私有成員命名時,前兩個字符是下劃線。(特殊成員除外,例如:init、call、dict等)
class C:
 
    def __init__(self):
        self.name = '公有字段'
        self.__foo = "私有字段"
class C:

    name = "公有靜態(tài)字段"
    __name = "私有靜態(tài)字段"
    
    def __init__(self):
        ...

類的特殊成員

# __doc__ 類的描述信息
class Foo:
    """ 描述類信息寫在這里 """
 
    def func(self):
        pass
print Foo.__doc__
#輸出:類的描述信息
# __module__ 表示當前操作的對象在哪個模塊
# __class__ 表示當前操作的對象的類是什么
# __init__ 構(gòu)造方法,創(chuàng)建對象時自動執(zhí)行
# __del__ 析構(gòu)方法,對象在內(nèi)存中釋放時自動觸發(fā)執(zhí)行
# __call__ call方法通過對象后加括號執(zhí)行
class Foo:
 
    def __init__(self):
        pass
 
    def __call__(self, *args, **kwargs):
 
        print '__call__'
 
obj = Foo() # 執(zhí)行 __init__
obj()       # 執(zhí)行 __call__
Foo()()     # 執(zhí)行 __call__
# __dict__ 顯示類或?qū)ο笏鶕碛械某蓡T
class Province:
 
    country = 'China'
 
    def __init__(self, name, count):
        self.name = name
        self.count = count
 
    def func(self, *args, **kwargs):
        print 'func'
 
# 獲取類的成員,即:靜態(tài)字段、方法
print Province.__dict__
# 輸出:{'country': 'China', '__module__': '__main__', 'func': , '__init__': , '__doc__': None}
 
obj1 = Province('HeBei',10000)
print obj1.__dict__
# 獲取 對象obj1 的成員
# 輸出:{'count': 10000, 'name': 'HeBei'}
 
obj2 = Province('HeNan', 3888)
print obj2.__dict__
# 獲取 對象obj2 的成員
# 輸出:{'count': 3888, 'name': 'HeNan'}
# __str__ 打印對象默認輸出該方法的返回值

Python中一切皆是對象

  • 類本身也是對象,并且類是由type類創(chuàng)建的
  • 類的創(chuàng)建也可以通過type類的構(gòu)造函數(shù)創(chuàng)建
def func(self):
    print 'hello xiaozhupeiqi'
 
Foo = type('Foo',(object,), {'func': func})
#type第一個參數(shù):類名
#type第二個參數(shù):當前類的基類
#type第三個參數(shù):類的成員
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容