python之路_面向对象进阶v
一、内置函数isinstance和issubclass
1、isinstance()
isinstance(obj,cls)检查obj是否是类 cls 的对象,类似type()。
class Foo(object):
pass
obj = Foo()
print(isinstance(obj, Foo)) #输出结果:True
print(isinstance(10,int)) #输出结果:True
sinstance() 与 type() 区别:type() 不会认为子类是一种父类类型,不考虑继承关系。sinstance() 会认为子类是一种父类类型,考虑继承关系。
class A:
pass
class B(A):
pass
isinstance(A(), A) # returns True
type(A()) == A # returns True
isinstance(B(), A) # returns True
type(B()) == A # returns False
(2)issubclass()
issubclass(sub, super)检查sub类是否是 super 类的派生类/子类
class Foo(object):
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo)) #输出结果:True
二、反射相关
python面向对象中的反射:通过字符串的形式操作对象相关的属性。如下为4个可以实现自省的函数:
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')) #输出结果:True
print(hasattr(obj,'say_hi')) #输出结果:True
#获取属性
n=getattr(obj,'name')
print(n) #输出结果:egon
func=getattr(obj,'say_hi')
func() #输出结果:hi,egon
#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__) #输出结果:{'name': 'egon', 'age': 73, 'sb': True, 'show_name': <function <lambda> at 0x00000194A8817048>}
print(obj.show_name(obj))
#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
print(obj.__dict__) #输出结果:{'name': 'egon', 'sb': True}
三、类的内置方法
1、__str__和__repr__
改变对象的字符串显示__str__,__repr__,这俩方法的返回值必须是字符串,否则抛出异常。
class Animal:
def __init__(self,kind,name):
self.kind = kind
self.name = name
def __str__(self):
return 'str : %s : %s'%(self.kind,self.name)
def __repr__(self):
return 'repr : %s : %s'%(self.kind,self.name)
cat = Animal('cat','guolei')
print(str(cat)) #输出结果:str : cat : guolei
print(repr(cat)) #输出结果:repr : cat : guolei
print('%s'%cat) #输出结果:str : cat : guolei
print('%r'%cat) #输出结果:repr : cat : guolei
2、__del__
析构方法,当对象在内存中被释放时,自动触发执行。注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1 #输出结果:执行我啦
3、__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 obj.key时,我执行
del f1['age'] #输出结果:del obj[key]时,我执行
f1['name']='alex'
print(f1.__dict__) #输出结果:{'name': 'alex'}
4、__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)
单例模式:
无论实例化多少个对象,只有一个对象存在,且这个对象为最后实例化的那个对象。
#实例1:
class Singleton:
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__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) # True
class Teacher:
__instance=None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance=object.__new__(cls)
return cls.__instance
def __init__(self,name,cloth):
self.name=name
self.cloth=cloth
刘老师=Teacher('liu','bai')
王老师=Teacher('wang','hei')
print(刘老师.name) #输出结果:wang
print(刘老师.cloth) #输出结果:cloth
5、__call__
对象后面加括号,触发执行。注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()。
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
6、__len__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a)) #输出结果:2
7、__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)) #输出结果:3429960989477292991
8.__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) #输出结果为:True
2、纸牌游戏2:洗牌
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃']
def __init__(self):
self._cards = [(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 shuffle
shuffle(deck)
print(deck[:5])
3、一道面试题
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))

浙公网安备 33010602011771号