標籤:類型 call ons 設定 item delattr 功能 nbsp text
一 isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)檢查是否obj是否是類 cls 的對象
class Foo(object):
pass obj = Foo() isinstance(obj, Foo)
issubclass(sub, super)檢查sub類是否是 super 類的衍生類別
class Foo(object): passclass Bar(Foo): passissubclass(Bar, Foo)
__setitem__,__getitem,__delitem__
在Python中,如果我們想實現建立類似於序列和映射的類,可以通過重寫魔法方法__getitem__、__setitem__、__delitem__方法去類比。
__getitem__(self,key):返回鍵對應的值。
__setitem__(self,key,value):設定給定鍵的值
__delitem__(self,key):刪除給定鍵對應的元素。
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): # print("getitem") return self.__dict__[item] def __setitem__(self, key, value): # print("setitem",key,value) self.__dict__[key]=value def __delitem__(self, key): # print(‘del obj[key]時,我執行‘) self.__dict__.pop(key)#如果沒有item方法,需要判斷obj的類型,函數將多出於功能無關的邏輯# def func(obj,key,value):# if isinstance(obj,dict):# obj[key]=value #obj[‘name‘]=‘123123‘# else:# setattr(obj,key,value)#加上item方法,則無需判斷obj的類型,不管是dict類型還是Foo類型,都以統一的一種[]的方式操作def func(obj,key,value): obj[key]=value #obj[‘name‘]=‘123123‘dic={‘name‘:‘egon‘,‘age‘:18}print(dic)obj=Foo(‘egon‘)func(dic,‘name‘,‘egon666‘)print(dic)print(obj.__dict__)func(obj,‘name‘,‘123123123123‘)print(obj.__dict__)#輸出結果{‘name‘: ‘egon‘, ‘age‘: 18}# {‘name‘: ‘egon666‘, ‘age‘: 18}# {‘name‘: ‘egon‘}# {‘name‘: ‘123123123123‘}__setitem__,__getitem,__delitem__
反射
1 什麼是反射
反射的概念是由Smith在1982年首次提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了電腦科學領域關於應用反射性的研究。它首先被程式語言的設計領域所採用,並在Lisp和物件導向方面取得了成績。
2 python物件導向中的反射:通過字串的形式操作對象相關的屬性。python中的一切事物都是對象(都可以使用反射)
說反射之前先介紹一下__import__方法,這個和import匯入模組的另一種方式
import commons__import__(‘commons‘)
如果是多層匯入:
from list.text import commons __import__(‘ list.text.commons‘,fromlist=True) #如果不加上fromlist=True,只會匯入list目錄
反射即想到4個內建函數分別為:getattr、hasattr、setattr、delattr 擷取成員、檢查成員、設定成員、刪除成員下面逐一介紹先看例子:
class BlackMedium: feature=‘Ugly‘ def __init__(self,name,addr): self.name=name self.addr=addr def sell_house(self): print(‘%s 黑中介賣房子啦,傻逼才買呢,但是誰能證明自己不傻逼‘ %self.name) def rent_house(self): print(‘%s 黑中介租房子啦,傻逼才租呢‘ %self.name)b1=BlackMedium(‘萬成置地‘,‘回龍觀天露園‘)#檢測是否含有某屬性print(hasattr(b1,‘name‘))print(hasattr(b1,‘sell_house‘))#擷取屬性n=getattr(b1,‘name‘)print(n)func=getattr(b1,‘rent_house‘)func()# getattr(b1,‘aaaaaaaa‘) #報錯print(getattr(b1,‘aaaaaaaa‘,‘不存在啊‘))#設定屬性setattr(b1,‘sb‘,True)setattr(b1,‘show_name‘,lambda self:self.name+‘sb‘)print(b1.__dict__)print(b1.show_name(b1))#刪除屬性delattr(b1,‘addr‘)delattr(b1,‘show_name‘)delattr(b1,‘show_name111‘)#不存在,則報錯print(b1.__dict__)
property
一個靜態屬性property本質就是實現了get,set,delete三種方法
1 class Goods: 2 3 def __init__(self): 4 # 原價 5 self.original_price = 100 6 # 折扣 7 self.discount = 0.8 8 9 @property10 def price(self):11 # 實際價格 = 原價 * 折扣12 new_price = self.original_price * self.discount13 return new_price14 15 @price.setter16 def price(self, value):17 self.original_price = value18 19 @price.deleter20 def price(self):21 del self.original_price22 23 24 obj = Goods()25 obj.price # 擷取商品價格26 obj.price = 200 # 修改商品原價27 print(obj.price)28 del obj.price # 刪除商品原價
property應用 __module__和__class__
__module__ 表示當前操作的對象在那個模組
__class__ 表示當前操作的對象的類是什麼
#!/usr/bin/env python# -*- coding:utf-8 -*-class C: def __init__(self): self.name = ‘SB‘
from lib.aa import Cobj = C()print obj.__module__ # 輸出 lib.aa,即:輸出模組print obj.__class__ # 輸出 lib.aa.C,即:輸出類
__call__
對象後面加括弧,觸發執行。
註:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括弧觸發的,即:對象() 或者 類()()
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print(‘__call__‘)obj = Foo() # 執行 __init__obj() # 執行 __call__
Python-物件導向進階