面向对象--反射

isinstance和issubclass

isinstance(obj,cls)检查对象obj是否是类cls的对象,返回True 或者 False

class Foo(object):
     pass
  
obj = Foo()
  
isinstance(obj, Foo)

issubclass(sub,super)检查sub类是否是super类的派生类,返回 True 或者 False

class Foo(object):
    pass
 
class Bar(Foo):
    pass
 
issubclass(Bar, Foo)

反射
什么是反射?

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

在Python面向对象中的反射:通过字符串的形式操作对象相关的属性。Python中的一切事物都是对象(都可以使用反射)。

主要用到四个函数:hasattr getattr setattr delattr

class Info:
    dic = {'student_info':'show_student','teacher_info':'show_teacher'}

    def show_student(self):
        print('show student')

    def show_teacher(self):
        print('show teacher')

for k in Info.dic:
    print(k)

ret = input('>>>')
print(type(ret),ret)
alex = Info()
if hasattr(alex, Info.dic[ret]):
    get = getattr(alex, Info.dic[ret])
    get()
else:
    print('Input Error')

getattr

#  getattr
# 反射对象的属性
# 反射对象的方法
# 变量名 = getattr(对象,'对象或类里的属性名') 相当于 类名.属性 # getattr 调用方法 # 变量名 = getattr(对象,'对象或类里的方法') # 相当于拿到方法的内存地址,如果要调用需要自己加括号 # 变量名() # 调用
# 反射类的属性和方法
# 反射对自定义的模块和内置模块也可以用
# 反射自身模块中的变量
# getattr
class A:
    def display(self):
        print('A')

a= A()
msg = input('>>>>')
ret = getattr(a,msg)
ret()
# 反射自己模块中的变量
def func():
    print('hahahaha')

year = 2019
import sys
print(sys.modules)
print(sys.modules['__main__'].year)
# 反射
print(getattr(sys.modules['__main__'],'year'))
print(getattr(sys.modules['__main__'],'func'))
print(getattr(sys.modules['__main__'],'func')())

# 如果导入模块后__main__就会改变,那么就将__main__改为一个变量
# # 需求,导入time模块,随意输入方法,显示内容
import time
print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(getattr(time,'strftime')('%Y-%m-%d %H:%M:%S'))
print(getattr(time,'asctime')())

hasattr

# 如果遇到输入的字符串不存在,程序就会报错,怎么修复这个问题呢?
# 解决方法: 使用hasasttr 先做判断,如果有就接着往下,没有就抛出异常
# hasattr 和 getattr 做搭配
# if hasattr(类名或对象名,'类里的属性名或方法名'):
#     变量名 = getattr(类名或对象,'类里的属性名或方法名')
#     # 若使用的是方法
#     # 变量名()
# else:
#     pass
class A:
    def display(self):
        print('A')

a= A()
msg = input('>>>>')
if hasattr(a,msg):
    ret = getattr(a,msg)
    ret()
else:
    print('输入有误')

setattr

# setattr 设置修改变量
class A:
    pass
a = A()
setattr(a,'name','jerry') # 在对象的内存空间里创建一个name
setattr(A,'name','Tom')  # 在类的内存空间创建了一个name
print(A.name)
print(a.name)

delattr

# delattr 删除一个变量
delattr(a,'name')  # 删除了对象内存空间里的name
print(a.name) # 找到父类的name后就输出
delattr(A,'name')  # 删除类内存空间的name
print(a.name)  # 没找到 所以报错了
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__)
完整实例

 

posted on 2019-04-17 17:25  Jerry-Wang  阅读(149)  评论(0)    收藏  举报