isinstance和issubclass
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 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省),這一概念的提出很快引發了計算機科學領域關于應用反射性的研究,它首先被程式語言的設計領域所采用,并在Lisp和面向物件方面取得了成績,
2 python面向物件中的反射:通過字串的形式操作物件相關的屬性,python中的一切事物都是物件(都可以使用反射)
四個可以實作自省的函式
下列方法適用于類和物件(一切皆物件,類本身也是一個物件)
def hasattr(*args, **kwargs): # real signature unknown """ Return whether the object has an attribute with the given name. This is done by calling getattr(obj, name) and catching AttributeError. """ passhasattr
def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ passgetattr
def setattr(x, y, v): # real signature unknown; restored from __doc__ """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v'' """ passsetattr
def delattr(x, y): # real signature unknown; restored from __doc__ """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """ passdelattr
class Foo: f = '類的靜態變數' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('egon',73) #檢測是否含有某屬性 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) #獲取屬性 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() print(getattr(obj,'aaaaaaaa','不存在啊')) #報錯 #設定屬性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) #洗掉屬性 delattr(obj,'age') delattr(obj,'show_name') delattr(obj,'show_name111')#不存在,則報錯 print(obj.__dict__)四個方法的使用演示
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 -*- import sys def s1(): print 's1' def s2(): print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')反射當前模塊成員
匯入其他模塊,利用反射查找該模塊是否存在某個方法
#!/usr/bin/env python # -*- coding:utf-8 -*- def test(): print('from the test')View Code
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 程式目錄: module_test.py index.py 當前檔案: index.py """ import module_test as obj #obj.test() print(hasattr(obj,'test')) getattr(obj,'test')()
__str__和__repr__
改變物件的字串顯示__str__,__repr__
自定制格式化字串__format__
#_*_coding:utf-8_*_ format_dict={ 'nat':'{obj.name}-{obj.addr}-{obj.type}',#學校名-學校地址-學校型別 'tna':'{obj.type}:{obj.name}:{obj.addr}',#學校型別:學校名:學校地址 'tan':'{obj.type}/{obj.addr}/{obj.name}',#學校型別/學校地址/學校名 } class School: def __init__(self,name,addr,type): self.name=name self.addr=addr self.type=type def __repr__(self): return 'School(%s,%s)' %(self.name,self.addr) def __str__(self): return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec): # if format_spec if not format_spec or format_spec not in format_dict: format_spec='nat' fmt=format_dict[format_spec] return fmt.format(obj=self) s1=School('oldboy1','北京','私立') print('from repr: ',repr(s1)) print('from str: ',str(s1)) print(s1) ''' str函式或者print函式--->obj.__str__() repr或者互動式解釋器--->obj.__repr__() 如果__str__沒有被定義,那么就會使用__repr__來代替輸出 注意:這倆方法的回傳值必須是字串,否則拋出例外 ''' print(format(s1,'nat')) print(format(s1,'tna')) print(format(s1,'tan')) print(format(s1,'asfdasdffd'))View Code
class B: def __str__(self): return 'str : class B' def __repr__(self): return 'repr : class B' b=B() print('%s'%b) print('%r'%b)%s和%r
item系列
__getitem__\__setitem__\__delitem__
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]時,我執行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key時,我執行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)View Code
__del__
析構方法,當物件在記憶體中被釋放時,自動觸發執行,
注:此方法一般無須定義,因為Python是一門高級語言,程式員在使用時無需關心記憶體的分配和釋放,因為此作業都是交給Python解釋器來執行,所以,解構式的呼叫是由解釋器在進行垃圾回收時自動觸發執行的,
class Foo: def __del__(self): print('執行我啦') f1=Foo() del f1 print('------->') #輸出結果 執行我啦 ------->簡單示范
__new__
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A) a = A() print(a.x)View Code
class Singleton: def __new__(cls, *args, **kw): if not hasattr(cls, '_instance'): cls._instance = object.__new__(cls) return cls._instance one = Singleton() two = Singleton() two.a = 3 print(one.a) # 3 # one和two完全相同,可以用id(), ==, is檢測 print(id(one)) # 29097904 print(id(two)) # 29097904 print(one == two) # True print(one is two)單例模式
__call__
物件后面加括號,觸發執行,
注:構造方法的執行是由創建物件觸發的,即:物件 = 類名() ;而對于 __call__ 方法的執行是由物件后加括號觸發的,即:物件() 或者 類()()
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 執行 __init__ obj() # 執行 __call__
with和__enter__,__exit__
class A: def __enter__(self): print('before') def __exit__(self, exc_type, exc_val, exc_tb): print('after') with A() as a: print('123')with陳述句
class A: def __init__(self): print('init') def __enter__(self): print('before') def __exit__(self, exc_type, exc_val, exc_tb): print('after') with A() as a: print('123')with陳述句和init
class Myfile: def __init__(self,path,mode='r',encoding = 'utf-8'): self.path = path self.mode = mode self.encoding = encoding def __enter__(self): self.f = open(self.path, mode=self.mode, encoding=self.encoding) return self.f def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() with Myfile('file',mode='w') as f: f.write('wahaha')with和檔案操作
import pickle class MyPickledump: def __init__(self,path): self.path = path def __enter__(self): self.f = open(self.path, mode='ab') return self def dump(self,content): pickle.dump(content,self.f) def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() class Mypickleload: def __init__(self,path): self.path = path def __enter__(self): self.f = open(self.path, mode='rb') return self def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() def load(self): return pickle.load(self.f) def loaditer(self): while True: try: yield self.load() except EOFError: break # with MyPickledump('file') as f: # f.dump({1,2,3,4}) with Mypickleload('file') as f: for item in f.loaditer(): print(item)with和pickle
import pickle class MyPickledump: def __init__(self,path): self.path = path def __enter__(self): self.f = open(self.path, mode='ab') return self def dump(self,content): pickle.dump(content,self.f) def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() class Mypickleload: def __init__(self,path): self.path = path def __enter__(self): self.f = open(self.path, mode='rb') return self def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() def __iter__(self): while True: try: yield pickle.load(self.f) except EOFError: break # with MyPickledump('file') as f: # f.dump({1,2,3,4}) with Mypickleload('file') as f: for item in f: print(item)with和pickle和iter
__len__
class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a))View Code
__hash__
class A: def __init__(self): self.a = 1 self.b = 2 def __hash__(self): return hash(str(self.a)+str(self.b)) a = A() print(hash(a))View Code
__eq__
class A: def __init__(self): self.a = 1 self.b = 2 def __eq__(self,obj): if self.a == obj.a and self.b == obj.b: return True a = A() b = A() print(a == b)View Code
class FranchDeck: ranks = [str(n) for n in range(2,11)] + list('JQKA') suits = ['紅心','方板','梅花','黑桃'] def __init__(self): self._cards = [Card(rank,suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits] def __len__(self): return len(self._cards) def __getitem__(self, item): return self._cards[item] deck = FranchDeck() print(deck[0]) from random import choice print(choice(deck)) print(choice(deck))紙牌游戲1
class FranchDeck: ranks = [str(n) for n in range(2,11)] + list('JQKA') suits = ['紅心','方板','梅花','黑桃'] def __init__(self): self._cards = [Card(rank,suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits] def __len__(self): return len(self._cards) def __getitem__(self, item): return self._cards[item] def __setitem__(self, key, value): self._cards[key] = value deck = FranchDeck() print(deck[0]) from random import choice print(choice(deck)) print(choice(deck)) from random import shuffle shuffle(deck) print(deck[:5])紙牌游戲2
class Person: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def __hash__(self): return hash(self.name+self.sex) def __eq__(self, other): if self.name == other.name and self.sex == other.sex:return True p_lst = [] for i in range(84): p_lst.append(Person('egon',i,'male')) print(p_lst) print(set(p_lst))一道面試題
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/194776.html
標籤:Python
上一篇:Python_初識面向物件
