目录
isinstance 和 issubclass
反射
setattr
delattr
getattr
hasattr
__str__ 和 __repr__
__del__
item系类
__getiem__
__setitem__
__delitem__
__new__
__call__
__len__
__hash__
__eq__
isinstance 和 issubclass
isinstance(obj,cls) 检查是否 obj 是否是类 cls 对象
class Foo(object):
pass
obj = Foo()
print(isinstance(obj,Foo)) #True
issubclass(sub,super) 检查sub类是否是supper类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
print(issubclass(Bar,Foo)) #True
反射
1、什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检查和修改它本身状态或行为的一种能力(自省),这一概念的提出很快引发了计算机科学领域关于应用反射性的研究,它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩
2、Python面向对象中的反射:通过字符串的形式操作操作对象相关的属性,Python中一切事物都是对象 (都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象 (一切皆对象,类本身也是一个对象)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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__)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
True
True
egon
hi,egon
不存在啊
{'name': 'egon', 'age': 73, 'sb': True, 'show_name': <function <lambda> at 0x0000000001D22EA0>}
egonsb
AttributeError: show_name111
{'name': 'egon', 'sb': True}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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'))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
old boy
<function Foo.func at 0x0000000001E79A60>
<function Foo.bar at 0x0000000001E79B70>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import sys
def s1():
print 's1'
def s2():
print 's2'
this_module = sys.modules[__name__]
hasattr(this_module, 's1')
getattr(this_module, 's2')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
True
<function s2 at 0x0000000001E99C80>
导入其他模块,利用反射查找该模块是否存在某个方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def test():
print('from the test')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""
程序目录:
module_test.py
index.py
当前文件:
index.py
"""
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
True
from the test
__str__和__repr__
改变对象的字符串显示__str__,__repr__
自定制格式化字符串__format__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#_*_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'))
=======执行结果===================
from repr: School(oldboy1,北京)
from str: (oldboy1,北京)
(oldboy1,北京)
oldboy1-北京-私立
私立:oldboy1:北京
私立/北京/oldboy1
oldboy1-北京-私立
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class B:
def __str__(self):
return 'str : class B'
def __repr__(self):
return 'repr : class B'
b = B()
print('%s' % b)
print('%r' % b)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
str : class B
repr : class B
__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1
print('------->')
#输出结果
执行我啦
------->
item系列
__getitem__\__setitem__\__delitem__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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__)
========执行结果=============
del obj.key时,我执行
del obj[key]时,我执行
{'name': 'alex'}
__new__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) ================ in new function in init function 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) ========================= 3 32145192 32145192 True True
__call__
对象后面加括号,触发执行
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
__len__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
__hash__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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))
__eq__
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
('2', '红心') ('7', '红心') ('J', '梅花')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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])
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[('3', '红心'), ('4', '梅花'), ('A', '方块'), ('K', '黑桃'), ('Q', '红心')]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[<__main__.Person object at 0x00000000026F7E48>, <__main__.Person object at 0x00000000026F7F98>, <__main__.Person object at 0x00000000026F7FD0>, <__main__.Person object at 0x0000000002702048>, <__main__.Person object at 0x0000000002702080>, <__main__.Person object at 0x00000000027020B8>, <__main__.Person object at 0x00000000027020F0>, <__main__.Person object at 0x0000000002702128>, <__main__.Person object at 0x0000000002702160>, <__main__.Person object at 0x0000000002702198>, <__main__.Person object at 0x00000000027021D0>, <__main__.Person object at 0x0000000002702208>, <__main__.Person object at 0x0000000002702240>, <__main__.Person object at 0x0000000002702278>, <__main__.Person object at 0x00000000027022B0>, <__main__.Person object at 0x00000000027022E8>, <__main__.Person object at 0x0000000002702320>, <__main__.Person object at 0x0000000002702358>, <__main__.Person object at 0x0000000002702390>, <__main__.Person object at 0x00000000027023C8>, <__main__.Person object at 0x0000000002702400>, <__main__.Person object at 0x0000000002702438>, <__main__.Person object at 0x0000000002702470>, <__main__.Person object at 0x00000000027024A8>, <__main__.Person object at 0x00000000027024E0>, <__main__.Person object at 0x0000000002702518>, <__main__.Person object at 0x0000000002702550>, <__main__.Person object at 0x0000000002702588>, <__main__.Person object at 0x00000000027025C0>, <__main__.Person object at 0x00000000027025F8>, <__main__.Person object at 0x0000000002702630>, <__main__.Person object at 0x0000000002702668>, <__main__.Person object at 0x00000000027026A0>, <__main__.Person object at 0x00000000027026D8>, <__main__.Person object at 0x0000000002702710>, <__main__.Person object at 0x0000000002702748>, <__main__.Person object at 0x0000000002702780>, <__main__.Person object at 0x00000000027027B8>, <__main__.Person object at 0x00000000027027F0>, <__main__.Person object at 0x0000000002702828>, <__main__.Person object at 0x0000000002702860>, <__main__.Person object at 0x0000000002702898>, <__main__.Person object at 0x00000000027028D0>, <__main__.Person object at 0x0000000002702908>, <__main__.Person object at 0x0000000002702940>, <__main__.Person object at 0x0000000002702978>, <__main__.Person object at 0x00000000027029B0>, <__main__.Person object at 0x00000000027029E8>, <__main__.Person object at 0x0000000002702A20>, <__main__.Person object at 0x0000000002702A58>, <__main__.Person object at 0x0000000002702A90>, <__main__.Person object at 0x0000000002702AC8>, <__main__.Person object at 0x0000000002702B00>, <__main__.Person object at 0x0000000002702B38>, <__main__.Person object at 0x0000000002702B70>, <__main__.Person object at 0x0000000002702BA8>, <__main__.Person object at 0x0000000002702BE0>, <__main__.Person object at 0x0000000002702C18>, <__main__.Person object at 0x0000000002702C50>, <__main__.Person object at 0x0000000002702C88>, <__main__.Person object at 0x0000000002702CC0>, <__main__.Person object at 0x0000000002702CF8>, <__main__.Person object at 0x0000000002702D30>, <__main__.Person object at 0x0000000002702D68>, <__main__.Person object at 0x0000000002702DA0>, <__main__.Person object at 0x0000000002702DD8>, <__main__.Person object at 0x0000000002702E10>, <__main__.Person object at 0x0000000002702E48>, <__main__.Person object at 0x0000000002702E80>, <__main__.Person object at 0x0000000002702EB8>, <__main__.Person object at 0x0000000002702EF0>, <__main__.Person object at 0x0000000002702F28>, <__main__.Person object at 0x0000000002702F60>, <__main__.Person object at 0x0000000002702F98>, <__main__.Person object at 0x0000000002702FD0>, <__main__.Person object at 0x0000000002705048>, <__main__.Person object at 0x0000000002705080>, <__main__.Person object at 0x00000000027050B8>, <__main__.Person object at 0x00000000027050F0>, <__main__.Person object at 0x0000000002705128>, <__main__.Person object at 0x0000000002705160>, <__main__.Person object at 0x0000000002705198>, <__main__.Person object at 0x00000000027051D0>, <__main__.Person object at 0x0000000002705208>] {<__main__.Person object at 0x00000000026F7E48>}