閱讀目錄
1,isinstance和issubclass
2,反射
- setattr
- delattr
- getattr
- hasattr
3,__str__和repr
4,__del__
5,item系列
- __getitem__
- __setitem__
- __delitem__
6,__new__
7,__call__
8,__len__
9,__hash__
10,__eq__
1,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)
2,反射
==1 什么是反射==
反射的概念是由Smith在1982年首次提出的晕鹊,主要是指程序可以訪問松却、檢測和修改它本身狀態(tài)或行為的一種能力(自省)溅话。這一概念的提出很快引發(fā)了計算機(jī)科學(xué)領(lǐng)域關(guān)于應(yīng)用反射性的研究晓锻。它首先被程序語言的設(shè)計領(lǐng)域所采用,并在Lisp和面向?qū)ο蠓矫嫒〉昧顺煽儭?br>
==2 python面向?qū)ο笾械姆瓷洌?= 通過字符串的形式操作對象相關(guān)的屬性。python中的一切事物都是對象(都可以使用反射)
四個可以實現(xiàn)自省的函數(shù)
下列方法適用于類和對象(一切皆對象飞几,類本身也是一個對象)
hasattr
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.
"""
pass
getattr
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.
"""
pass
setattr
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''
"""
pass
delattr
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''
"""
pass
四個方法的使用演示
class Foo:
f = '類的靜態(tài)變量'
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','不存在啊')) #報錯
#設(shè)置屬性
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__)
3砚哆,str和repr
改變對象的字符串顯示str,__repr__
自定制格式化字符串format
#_*_coding:utf-8_*_
format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#學(xué)校名-學(xué)校地址-學(xué)校類型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#學(xué)校類型:學(xué)校名:學(xué)校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#學(xué)校類型/學(xué)校地址/學(xué)校名
}
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函數(shù)或者print函數(shù)--->obj.__str__()
repr或者交互式解釋器--->obj.__repr__()
如果__str__沒有被定義,那么就會使用__repr__來代替輸出
注意:這倆方法的返回值必須是字符串,否則拋出異常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))
%s和%r
class B:
def __str__(self):
return 'str : class B'
def __repr__(self):
return 'repr : class B'
b=B()
print('%s'%b)
print('%r'%b)
4,del
析構(gòu)方法屑墨,當(dāng)對象在內(nèi)存中被釋放時躁锁,自動觸發(fā)執(zhí)行。
注:此方法一般無須定義卵史,因為Python是一門高級語言战转,程序員在使用時無需關(guān)心內(nèi)存的分配和釋放,因為此工作都是交給Python解釋器來執(zhí)行以躯,所以槐秧,析構(gòu)函數(shù)的調(diào)用是由解釋器在進(jìn)行垃圾回收時自動觸發(fā)執(zhí)行的。
==簡單示范==
class Foo:
def __del__(self):
print('執(zhí)行我啦')
f1=Foo()
del f1
print('------->')
#輸出結(jié)果
執(zhí)行我啦
------->
5忧设,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]時,我執(zhí)行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key時,我執(zhí)行')
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__)
6,__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, *args, **kwargs)
a = A()
print(a.x)
單例模式
class Singleton:
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls, *args, **kw)
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)
7,__call__
對象后面加括號刁标,觸發(fā)執(zhí)行。
注:構(gòu)造方法的執(zhí)行是由創(chuàng)建對象觸發(fā)的址晕,即:對象 = 類名() 膀懈;而對于 call 方法的執(zhí)行是由對象后加括號觸發(fā)的,即:對象() 或者 類()()
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() ## 執(zhí)行 __init__
obj() ## 執(zhí)行 __call__
8,__len__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
9,__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))
10,__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)
紙牌游戲
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))
紙牌游戲2
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])
一道面試題
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))