• python学习 day018打卡 反射


    本节主要内容:

    1.isinstance,type,issubclass

    2.区分函数和方法

    3.反射(重点)

    一.isinstance,type,issubclass

    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)) # Ture

    type(obj):查看obj是由哪个类创建的.

    class Foo:
        pass
    
    obj = Foo()
    print(type(obj))    # <class '__main__.Foo'>

    type()可以帮我们判断xxx是否是xxx数据类型的

    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(),Boy(),Girl(),Boy(),Girl(),Boy())
    print(ret)

     isinstance() 也可以判断xxx是否是xxx类型的数据,但是isinstance没有issubclass() 那么精准.

    class Base:
        pass
    
    class Foo(Base):
        pass
    
    class Bar(Foo):
        pass
    
    print(isinstance(Bar,Foo))  # True
    print(isinstance(Foo,Bar))  # False
    print(isinstance(Bar,Base)) # False

    isinstance可以判断该对象是否是xxx家族体系中的(只能往上判断)

    二,区分函数和方法

    def func():
        pass
    
    print(func) #<function func at 0x00000265B9E12E18>
    
    class Foo:
        def chi(self):
            print("我是吃")
    
    foo = Foo()
    print(foo.chi)  # <bound method Foo.chi of <__main__.Foo object at 0x00000265BA00C908>>

      函数在打印的时候,很明显显示的是function.而方法在打印的时候很明显是method.但是在类里面就不一定了:

    class Foo:
    
        def chi(self):
            print("我是吃")
    
        @staticmethod
        def static_method():
            pass
    
        @classmethod
        def class_method(cls):
            pass
        
    f = Foo()
    print(f.chi)    # <bound method Foo.chi of <__main__.Foo object at 0x0000016B23AEC978>>
    print(Foo.chi)  # <function Foo.chi at 0x0000016B23ACDF28>
    print(Foo.static_method)    # <function Foo.static_method at 0x0000016B23AF4048>
    print(Foo.class_method) # <bound method Foo.class_method of <class '__main__.Foo'>>
    print(f.static_method)  # <function Foo.static_method at 0x0000016B23AF4048>
    print(f.class_method)   # <bound method Foo.class_method of <class '__main__.Foo'>>

    通过观察上面代码的结果,我们可以得出以下结论:

    1.类方法.不论任何情况,都是方法.

    2.静态方法,不论任何情况,都是函数.

    3.实例方法,如果是对象去访问,就是方法.如果是类名访问就是函数.

    我们可以通过借助types模块来帮我们分辨到底谁是函数,谁方法

    from types import FunctionType, MethodType
    
    class Car:
        def run(self): # 实例方法
            print("我是车, 我会跑")
    
        @staticmethod
        def cul():
            print("我会计算")
    
        @classmethod
        def jump(cls):
            print("我会jump")
    
    
    # 实例方法:
    #     1. 用对象.方法   方法
    #     2. 类名.方法     函数
    c = Car()
    # print(isinstance(c.run, FunctionType)) # False
    # print(isinstance(Car.run, FunctionType)) # True
    # print(isinstance(c.run, MethodType)) # True
    # print(isinstance(Car.run, MethodType)) # False
    
    # 静态方法 都是函数
    # print(isinstance(c.cul, FunctionType)) # True
    # print(isinstance(Car.cul, FunctionType)) # True
    # print(isinstance(c.cul, MethodType)) # False
    # print(isinstance(Car.cul, MethodType)) # False
    
    # 类方法都是方法
    print(isinstance(c.jump, FunctionType)) # False
    print(isinstance(Car.jump, FunctionType)) # False
    print(isinstance(c.jump, MethodType)) # True
    print(isinstance(Car.jump, MethodType)) # True
    
    # FunctionType:函数
    # MethodType: 方法

    插入: 我们写的类也可以看做是对象,类的类型是type,即type(类) ==><class 'type'>

    三.反射

    反射:所谓反射就是通过字符串来动态访问模块中的功能.通过手动输入需要运行的功能,反着去模块里找,这个就叫反射

    # master.py
    
    def chi():
        print("大牛很能吃")
    
    def he():
        print("大牛从来不喝")
    
    
    def la():
        print("大牛就知道拉")
    
    def sa():
        print("大牛说撒是什么")
    import master
    
    while True:
        s = input("请输入你要测试的功能:")
    
        if hasattr(master,s):
            func = getattr(master,s)
            func()
        else:
            print("你输入的是个啥玩意儿啊")

    里面涉及到的两个函数---getattr(), hasattr()

    getattr()用来获取信息

    hasattr()用来判断xxx中是否包含了xxx功能.

    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 方法

     总结,getattr()可以从模块中获取内容,也可以从类中获取内容,也可以从对象中获取内容.在python中一切皆为对象,那可以这样认为.getattr从对象中动态的获取成员

    关于反射,一共有4个函数:

    1.hasattr(obj,str)判断obj中是否包含str成员

    2.getattr(obj,str)从obj中获取str成员

    3.setattr(obj,str,value)吧obj中的str成员设置成value.注意,这里的value可以是值,也可以是函数或者方法.如果str不存在,就创建新的成员,把值赋值给新成员

    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
    print(f.chi) # 此时的chi既不是静态方法,也不是实例方法,更不是类方法.就相当于你在类中写了个self.chi = lambda 是一样的
    print(f.__dict__)   # {'chi': <function <lambda> at 0x00000238E1392E18>}
    
    delattr(f,"chi")
    print(hasattr(f,"chi")) # False
  • 相关阅读:
    shaderlab
    Unity
    Lua-闭包
    Unity- 小“东西”
    3.神经网络的保存、神经网络提取的2 ways
    2.搭建pytorch神经网络的常用两种方式
    搭建pytorch神经网络的常用两种方式
    1.建立第一个神经网络-关系拟合 (回归)
    python的编码解码问题
    github的搜素小技巧
  • 原文地址:https://www.cnblogs.com/af1y/p/9936548.html
Copyright © 2020-2023  润新知