python之路----面向对象进阶一
一、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)
二、反射
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
上述方法的使用
1.反射对象中的属性和方法
class A:
def func(self):
print('in func')
a = A()
a.name = 'alex'
a.age = 63
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ret = getattr(a,'name') # 通过变量名的字符串形式取到的值
print(ret)
print(a.__dict__)
变量名 = input('>>>') # func
print(getattr(a,变量名))
print(a.__dict__[变量名])
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a.func()
ret = getattr(a,'func')
ret()
2.反射类中的属性和方法
class A:
price = 20
@classmethod
def func(cls):
print('in func')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# A.price
print(getattr(A,'price'))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# A.func()
if hasattr(A,'func'):
getattr(A,'func')()
3.反射模块中的属性和方法
import my
反射模块的属性
print(my.day)
print(getattr(my,'day'))
反射模块的方法
getattr(my,'wahaha')()
4.内置模块的反射
time
asctime
import time
print(getattr(time,'time')())
print(getattr(time,'asctime')())
5.反射自己模块中的变量和函数
def qqxing():
print('qqxing')
year = 2018
import sys
print(sys.modules['__main__'].year)
反射自己模块中的变量
print(getattr(sys.modules['__main__'],'year'))
反射自己模块中的函数
getattr(sys.modules['__main__'],'qqxing')()
6.要反射的函数有参数怎么办?
# print(time.strftime('%Y-%m-%d %H:%M:S'))
# print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))
7.setattr 设置修改变量
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
setattr 设置修改变量
class A:
pass
a = A()
setattr(a,'name','nezha')
setattr(A,'name','alex')
print(A.name)
print(a.name)
8. delattr 删除一个变量
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# delattr 删除一个变量
delattr(a,'name')
print(a.name)
delattr(A,'name')
print(a.name)
9四个方法的使用演示
![](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__)
四个方法的使用演示
三、内置的类方法 :和内置的函数之间有着千丝万缕的联系
__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'))
![](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)
%s和%r
__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Foo:
def __del__(self):
print('执行我啦')
f1=Foo()
del f1
print('------->')
#输出结果
执行我啦
------->
简单示范