反射、isinstance和issubclass

isinstance和issubclass

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

print(isinstance(1,int))#输出:True
print(isinstance("abc",str))#输出:True
print(isinstance([],list))#输出:True
#判断第一个参数是你是第二个参数的实例

class A:pass
class B(A):pass
class C(B):pass
c = C()
print(isinstance(c,B)) # 包含继承关系的判断 True
print(type(c) is B) #False
print(type(c) is A) # type只关心创建这个对象的类 False
 

issubclass(sub, super)检查sub类是否是 super 类的派生类 

class A:pass
class B(A):pass
print(issubclass(A,B))   #False
print(issubclass(B,A))   #True
# 第一个参数是疑似子类,第二个参数是疑似父类.
# 最终结果如果真的是父子类关系,则返回True

反射

1 什么是反射

反射的定义 : 通过字符串 来 操作python代码中的 变量 函数 甚至类和方法

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

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

getattr()、hasattr()、setattr()、delattr()

反射静态方法:

class A:
    name = 'alex'   # 静态 属性
    age = 83        # 静态 属性
print(getattr(A,'name'))  #可以直接操作字符串 输出:alex
                           #如果第二个参数没有,会报错,所有先用hasattr 判断
print(hasattr(A,'name'))  #输出:True
tag=input(">>>")
if hasattr(A,tag): #先判断,再getattr()避免报错
    print(getattr(A,tag)
#用字符串调用方法
class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show(self):
        for key in self.__dict__:
            print(key,self.__dict__[key])
lin=Student("liulin",123)
print(hasattr(lin,"show"))  #True 证明实例化的这个对象里面有show方法
print(getattr(lin,"show"))  #输出方法的内存地址,想调用后面加()
f=getattr(lin,"show")
f()# 输出:name liulin
   #       age 123

setattr()增改操作

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show(self):
        for key in self.__dict__:
            print(key,self.__dict__[key])
hei = Student('小黑',18)
hei.show()
hei.sex = ''   #正常方法加一个属性
setattr(hei,'sex','不详')  # setattr方法实现字符串对类的增改操作,三个参数(对象,属性,属性值)
print(hei.sex)

delattr()删除操作

delattr(hei,'sex')    # 删除操作
print(hei.__dict__)

小结:

hasattr  判断某一个 变量 是否能够.调用一个名字,返回True或者False
getattr 直接获取一个变量中的名字的值
setattr 为一个变量增加或者修改一个属性 三个参数:setattr(对象,属性,属性值)
delattr 删除一个变量中的属性或者方法

操作模块:

import my_moudle   #引用模块
print(my_moudle.money)  
print(getattr(my_moudle,'money'))    #用字符串执行模块的属性  
getattr(my_moudle,'qqxing')()       #用字符串执行模块的方法

 反射当前模块

sys.modules[“__main__"]  :找到当前模块

 由于__main__在一个py文件里被其他py文件作为模块导入,则__main__值会发生改变,所以用__name__,保持原来的值

import sys
# print(sys.modules[__name__])  # 一定是当前.py
# print(sys.modules['__main__'])  # 不确定的,导到哪,就是哪的py
# print(getattr(sys.modules[__name__],'count'))
# getattr(sys.modules[__name__],'sww')()
# print(sys.modules[__name__])
# # print(sys.modules['my_moudle'])
# # print(my_moudle)
# print(getattr(sys.modules['my_moudle'],'qqxing'))
代码和注意事项

一共四种反射情况:

反射类中的名字
getattr(类名,'静态属性')
getattr(类名,'类方法')()
getattr(类名,'静态方法')()

反射对象中的名字
getattr(对象名,'对象属性')
getattr(对象名,'方法名')()

反射模块中的名字
import 模块名
getattr(模块名,'模块中的变量')
getattr(模块名,'模块中的函数')()
getattr(模块名,'模块中的类名')

反射当前模块中的名字
import sys
getattr(sys.modules[__name__],'变量')
getattr(sys.modules[__name__],'函数')()
getattr(sys.modules[__name__],'类名')

反射类:

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show_student(self):
        for key in self.__dict__:
            print(key,self.__dict__[key])
原文地址:https://www.cnblogs.com/pygg/p/8549211.html