zoukankan      html  css  js  c++  java
  • python学习笔记 day27 反射(二)

    1. isinstance(obj,cls)  ----查看obj是否为cls的对象;

        issubclass(sub,super)------查看sub是否为super的子类

    class A():
        pass
    a=A()
    print(isinstance(a,A))  # instance(obj,cls)查看obj是否为cls的对象
    class B(A):
        pass
    print(issubclass(B,A)) # issubclass(sub,super)查看sub是否为super的子类

     反射----根据变量的字符串形式获得变量的值;

    1.反射对象的属性  VS  反射对象的方法

    class Student():
        def __init__(self,name):
            self.name=name  # 对象属性
        def get_name(self):
            return self.name
    student=Student("璇璇")
    if hasattr(student,'name'):  # 查看对象student是否含有name属性(只是这里是name属性的字符串形式)
        ret=getattr(student,'name')
        print('使用反射获得对象的属性',ret)
    if hasattr(student,'get_name'):
        ret=getattr(student,'get_name')  # ret其实就是student.get_name 反射对象的方法,从对象方法的字符串形式获得该对对象的方法
        print("使用反射调用对象的方法:",ret())

    运行结果:

    2. 反射类中的属性和方法;

    class Person():
        country='China'  # 类属性,又叫静态属性
        @classmethod  # 定义类方法
        def func(cls):
            print("这是类方法,类属性的值为:",cls.country)
        @staticmethod
        def func2():
            print("这是静态方法,里面不需要传self,cls等就是放在类中的普通函数")
    if hasattr(Person,'country'):  # 查看类中是否有country静态属性
        ret=getattr(Person,'country')
        print("使用反射根据类中静态属性的字符串形式获得静态属性的值:",ret)
    if hasattr(Person,'func'):
        ret=getattr(Person,'func') # 使用反射根据类方法的字符串形式获得类方法ret ,ret相当于Person.func
        ret()
    if hasattr(Person,'func2'):  #反射类的静态方法
        ret=getattr(Person,'func2')
        ret()

    运行结果:

     3. 反射模块中的属性和方法:

    首先需要导入的模块 test.py中:

    # 这个模块需要被test1.py导入的,测试模块中的反射
    name='xuanxuan'
    def func():
        print("我是被导入模块test.py中的方法")
    import test # 导入test模块
    if hasattr(test,'name'): # 查看被导入的模块是否含有name属性,这里是name的字符串形式,
        ret=getattr(test,'name')  # 可以使用getattr对象属性的字符串形式获得对象的属性
        print("使用反射获得模块中属性的值:",ret)
    if hasattr(test,'func'):  # 查看模块test是否含有func方法
        ret=getattr(test,'func')
        ret()

    运行结果:

     4. 内置模块也可以使用反射

    比如用户输入time模块的一个方法名,需要用户输出time模块中该方法,但是我们不能直接使用,因为用户输入获得的是一个字符串形式的函数名,我们需要使用getattr(模块名,字符串形式的方法名)获得该模块的该方法

    import time
    func_name=input(">>>")
    if hasattr(time,func_name):  # 查看time模块是否含有func_name,只不过这里收到的是字符串形式
        func=getattr(time,func_name)  # 比如输入localtime, func就相当于time.localtime
        print(func())  # 输入localtime func()相当于time.localtime()

    运行结果:

     5. 反射自己模块中的属性和方法

    这里需要注意,当前py文件获得当前py文件(模块名)可以使用sys.modules字典中 __name__键对应的值,也即使用sys.modules[__name__]就可以获得当前的模块名(其实就是当前py文件的文件名);

    import sys
    name='xuanxuan'
    def func():
        return "我是当前文件中的方法"
    # 我们可以直接使用name,或者直接调用func()函数
    print(name)
    print(func())
    
    # 当然也可以使用这种方式来获得当前模块(当前py文件)的属性和方法:
    print(sys.modules[__name__])  # 可以打印当前模块名
    print("使用sys.modules[__name__]获得当前模块名,使用这种方式调用当前模块中的属性:",sys.modules[__name__].name)  # 这样也可以获得当前模块中的name变量,但是我们通常不去这样做,因为在自己的模块中就直接可以使用属性和方法
    print("使用sys.modules[__name__]来获得当前模块名,然后使用模块名.方法获得当前模块中的方法:",sys.modules[__name__].func())
    
    print("*******************接下来使用反射获得当前模块中的属性和方法,比如你在当前模块拿到的是'name'或者'func'这种字符串形式的")
    if hasattr(sys.modules[__name__],'name'):  # 查看当前模块sys.modules[__name__]是否含有name属性
        ret=getattr(sys.modules[__name__],'name')
        print("使用反射获得当前模块的name属性的值:",ret)
    if hasattr(sys.modules[__name__],'func'):  # 查看当前模块是否含有方法名func
        ret=getattr(sys.modules[__name__],'func')
        print('使用反射获得当前模块的方法func:',ret())

     运行结果:

     6. 一个模块中的类也可以使用反射获得:

    被导入模块test.py中的内容:

    # 这个模块需要被test1.py导入的,测试模块中的反射
    class A():
        def func(self):
            print("我是被导入的模块中的类 中的方法")
    import test
    if hasattr(test,'A'): # 查看导入的模块test中是否含有类A,但是有可能我们拿到的是字符串形式的'A'
        cls=getattr(test,'A')   # cls相当于test.A其实就是类A
        obj=cls()   # obj 其实相当于导入模块test中类A的对象
        obj.func()  # 可以使用类A的对象obj调用在类A中定义的方法func

    运行结果:

     总结:

    只要是可以用 什么.什么 的形式来调用的都可以使用反射来完成通过拿到的字符串形式,获得本来的值;

    setter ----设置修改属性 ;  delattr----删除属性

    class A():
        def func(self):
            print("类A中的方法")
    setattr(A,'name','名字') # 设置类A的类属性,静态属性,这个属性依然是字符串类型的,但是实际上操作的确是不带引号的
    print("类A中的name属性值:",A.name)  # 类属性
    a=A()
    setattr(a,'name','璇璇')  # 设置对象的name属性
    print("对象a中的name属性值:",a.name)

    运行结果:

    但是如果delattr删掉对象a中的name属性呢?

    class A():
        def func(self):
            print("类A中的方法")
    setattr(A,'name','名字') # 设置类A的类属性,静态属性,这个属性依然是字符串类型的,但是实际上操作的确是不带引号的
    print("类A中的name属性值:",A.name)  # 类属性
    a=A()
    setattr(a,'name','璇璇')  # 设置对象的name属性
    print("对象a中的name属性值:",a.name)
    delattr(a,'name')  # 反射中的一些方法,,操作的对象都素hi字符串类型的,我们就是想通过这些字符串类型的属性或者方法,来获得实际不带引号的属性和放啊
    print("删掉对象a中的name属性之后,对象的属性没有了,但是a.name时 由对象指针会去类中去找对应的属性:",a.name)

    运行结果:

    talk is cheap,show me the code
  • 相关阅读:
    Java io 理解
    Java应用的理解
    Flyweight 享元模式
    Bridge 桥梁模式
    Decrator 装饰模式
    [CF997C]Sky Full of Stars_二项式反演_等比数列_容斥原理
    [CF1010D]Mars Over_位运算性质
    [CF991D]Bishwock_状压dp
    [Agc030B]Tree Burning_贪心
    [Cometoj#4 E]公共子序列_贪心_树状数组_动态规划
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9690325.html
Copyright © 2011-2022 走看看