python019

核能来袭-反射 本节主要内容: 
1.isinstance,type,issubclass
2.区分函数和方法
3.反射(重点)
一.isinstance,type,issubclass
1.issubclass:这个内置函数可以帮我们判断xxx类是yyy类型的子类
class Base:
    pass
class Foo(Base):
    pass
class Bar(Foo):
    pass
print(issubclass(Bar,Foo))  #True
print(issubclass(Foo,Bar))  #False
print(issubclass(Bar,Base))  #True

2.type:可以帮我们判断xxx是否是xxx数据类型的
class Foo:
    pass
obj=Foo()
print(obj,type(obj))  #查看obj的类<__main__.Foo object at 0x000001D898FB82E8> <class '__main__.Foo'>
class Boy:
    pass
class Girl:
    pass
def func(*args):
#统计传进来的男生和女生分别是多少
    b=0
    g=0
    for obj in args:
        if type(obj)==Boy:
            b+=1
        elif type(obj)==Girl:
            g+=1
    return b,g
ret=func(Boy(),Girl(),Girl(),Girl(),Boy(),Girl(),Girl())
print(ret)
或者,你在进行计算的时候.先判断好要计算的数据类型必须是int或者float.这样计算才有意义.
def add(a,b):
    if (type(a)==int or type(a)==float ) and (type(b)==int or type(b)==float):
        return a+b
    else:
        print("我要报错")
View Code


3.isinstance:判断xxx是yyy类型的数据.但是isinstance没有type那么准确
class Base:
    pass
class Foo(Base):
    pass
class Bar(Foo):
    pass
print(isinstance(Foo(),Foo))  #True
print(isinstance(Foo(),Base)) #True
print(isinstance(Foo(),Bar))  #False
isinstance可以判断该对象是否是xxx家族体系中的(只能往上判断)

二.区别函数和方法
def func():
    pass
print(func)  #<function func at 0x0000022BE6C21F28>
class Foo:
    def chi(self):
        print("我是吃")
f=Foo()
print(f.chi)   #<bound method Foo.chi of <__main__.Foo object at 0x00000212A4798438>>
函数在打印的时候.显示的是function.而方法在打印的时候显示的methon
class Foo:
    def chi(self):
        print("我是吃")
    @staticmethod
    def static_methon():
        pass
    @classmethod
    def class_methon(cls):
        pass
f=Foo()
print(f.chi)    #<bound method Foo.chi of <__main__.Foo object at 0x0000010B091A84E0>>
print(Foo.chi)  #<function Foo.chi at 0x000001D40E2CA9D8>
print(Foo.static_methon)    #<function Foo.static_methon at 0x000001E457CAAA60>
print(Foo.class_methon)   #<bound method Foo.class_methon of <class '__main__.Foo'>>
print(f.static_methon)      #<function Foo.static_methon at 0x000001FC2CC3AA60>
print(f.class_methon)       #<bound method Foo.class_methon of <class '__main__.Foo'>>

 


结论: 
1.类方法,不论任何情况,都是方法.
2.静态方法,不论任何情况,都是函数.
3.实例方法,如果是实例访问就是方法.如果是你类名访问就是函数. 那如何用程序来帮我们分辨.到底是方法还是函数呢?
首先,我们要借助于types模块. 所有的方法都是MethonType的实例
所有的函数都是FunctionType的实例 from types import MethodType,FunctionType
三.反射. 
首先,我们看这样⼀个需求,说有个大牛, 写了⼀堆特别牛B的代码.然后放在了⼀个py 文件里(模块),这时, 你想用这个大牛写的东西.但是呢. 你首先得知道大牛写的这些代码都是干什么用的.那就需要你把大牛写的每一个函数跑一下.摘一摘自己想用的内容. 来咱们模拟 这样的需求,首先大牛给出一个模块.
#     大牛.py
# def chi():
#     print("大牛一顿吃100个螃蟹")
# def he():
#     print("大牛一顿喝100瓶可乐")
# def la():
#     print("大牛不用拉")
# def shui():
#     print("大牛一次睡一年")
# import master
# from types import FunctionType
# while 1:
#     print("""作为大牛帮你写了:
#     chi
#     he
#     la
#     shui
#     等""")
#     gn=input("请输入你要测试的功能:")
#     if hasattr(master,gn):
#         attr=getattr(master,gn)
#         if isinstance(attr,FunctionType):
#             attr()
#         else:
#             print(attr)
# class Person:
#     country="大清"
#     def chi(self):
#         pass
# print(getattr(Person,"country"))    #类中的内容可以这样动态的获取
# print(getattr(Person,"chi"))   #相当于Foo.func函数
# obj=Person()
# print(getattr(obj,"country"))
# print(getattr(obj,"chi"))   #相当于obj.func 方法
View Code

总结:getattr可以从模块中获取内容,也可以从类中获取内容,也可以从对象中获取内容.
关于反射,其实一共有4个函数:
1.hasattr(obj,str)判断obj中是否是包含str成员
2.getattr(obj,str)从obj中获取str成员
3.setattr(obj,str,value)把obj中的str成员设置成value.
注意:这里的value可以是值,也可以是函数或者方法
4.delattr(obj,str)把obj中的str成员删掉
class Foo:
    pass
f=Foo()
print(hasattr(f,"chi"))  #False
setattr(f,"chi","123")
print(f.chi)    #被添加一个属性信息
setattr(f,"chi",lambda x: x+1)
print(f.chi(3))   #4
delattr(f,"chi")
print(hasattr(f,"chi"))   #False

 



 


 

 




 



posted on 2018-09-28 18:02  向往未来666  阅读(124)  评论(0编辑  收藏  举报