Python对象、类以及模块的反射机制

所谓反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数并执行。Python有四个内置函数用来实现反射机制:

函数功能
getattr(object, attr[, default]) 获取指定字符串名称的对象属性或方法,如果对象有该属性则返回属性值,如果有该方法则返回该方法的内存地址,如果都没有就报错,如果指定了默认值找不到不会报错会取默认值
hasattr(object, attr) 判断指定字符串名称的对象是否有该属性或方法,返回True或False
setattr(object, attr, value) 为指定字符串名称的对象设置属性,如果对象已有该属性则覆盖属性值,如果没有该属性则新增属性并赋值
delattr(object, attr) 删除指定字符串名称的对象的某属性,如果对象没有该属性会报错

一、getattr方法的使用

1.1.通过对象获取

class Administrator:
    role = "管理员"

    def __init__(self, name, sex, phone, mail):
        self.name = name
        self.sex = sex
        self.phone = phone
        self.mail = mail

    def createClss(self):
        print("创建班级")

    def createTearcher(self):
        print("创建老师")

    def createStudent(self):
        print("创建学生")

admin = Administrator("张无忌","","15689765678","zhangwuji@126.com")

#通过对象获取对象方法
f = getattr(admin,"createClss")
f()

#通过对象获取对象属性
name = getattr(admin,"name")
print(name)

#通过对象获取类属性
role = getattr(admin, "role")
print(role)

#通过对象获取类属性,设置默认值
#hasattr用于判断对象是否具有该属性名,返回true或者false
import logging
if hasattr(admin, "role"):
    #如果有了则修改role1属性的值为 超级管理员
    role = getattr(admin, "role", "超级管理员")
    print(role)
else:
    logging.error("没有role属性")
    #可以返回设置属性的值
    role = getattr(admin, "role1", "超级管理员")
    print(role)

1.2.通过类获取

class Administrator:
    role = "管理员"

    def createClss(self):
        print("创建班级")

    def createTearcher(self):
        print("创建老师")

    def createStudent(self):
        print("创建学生")

    @staticmethod
    def crateSchool():
        print("创建学校")

#类获取

#通过类来获取的实例方法的时候,需要在调用方法中传入实例化对象
f = getattr(Administrator, "createClss")
f(Administrator)

# f = getattr(Administrator, "createClss")
#admin = Administrator("张无忌","男","15689765678","zhangwuji@126.com")
# f(admin)

#通过类来获取的静态方法的时候,直接调用即可
s = getattr(Administrator, "crateSchool")
s()

#获取类属性
role = getattr(Administrator, "role")
print(role)

二、setattr

2.1.设置类属性、方法

class Administrator:
    role = "管理员"

    def __init__(self, name, sex, phone, mail):
        self.name = name
        self.sex = sex
        self.phone = phone
        self.mail = mail

    def createClss(self):
        print("创建班级")

    def createTearcher(self):
        print("创建老师")

    def createStudent(self):
        print("创建学生")

    @staticmethod
    def crateSchool():
        print("创建学校")

#admin = Administrator("张无忌","男","15689765678","zhangwuji@126.com")

#设置类属性
setattr(Administrator, "area", "华东")
print(Administrator.area)

#删除类属性
delattr(Administrator, "area")
#删除类静态属性,在输出会报错
# print(Administrator.area)

#设置类方法(静态方法)
def create_grade():
    print("创建一个班级")
setattr(Administrator,"create_grade", create_grade)
Administrator.create_grade()

2.2.设置对象属性和方法

class Administrator:
    role = "管理员"

    def __init__(self, name, sex, phone, mail):
        self.name = name
        self.sex = sex
        self.phone = phone
        self.mail = mail

    def createClss(self):
        print("创建班级")

    def createTearcher(self):
        print("创建老师")

    def createStudent(self):
        print("创建学生")

    @staticmethod
    def crateSchool():
        print("创建学校")

admin = Administrator("张无忌","","15689765678","zhangwuji@126.com")

#设置对象属性
print(admin.name)
setattr(admin, "name", "张翠山")
print(admin.name)

#删除对象属性
print(admin.name)
delattr(admin, "name")
print(admin.name)


#根据对象不能删除静态属性
delattr(admin, "role")

#设置对象实例方法
def create_course(self):
    print("创建课程")
setattr(admin, "create_course", create_course)
#调用的时候
admin.create_course(admin)

#设置对象静态方法
def create_grade():
    print("创建一个班级")
setattr(admin, "create_grade", create_grade)
admin.create_grade()

三、模块反射

创建一个模块hello1.py内容如下:

description = "这是变量的值"
def sum_both(a, b):
    return a+b

在hello2.py中代码如下:

import hello1
​
#取出变量的值
a = getattr(hello1, "description")
print(a)
​
#取出函数
sum_both = getattr(hello1, "sum_both")
s = sum_both(4,6)
print(s)

四、反射本模块函数、变量

import sys

description = "这是变量的值"
def sum_both(a, b):
    return a+b

#获取当前模块对象
print(sys.modules[__name__])
#获取当前模块中 description变量对象
print(getattr(sys.modules[__name__], "description"))

#获取模块函数对象
s = getattr(sys.modules[__name__],"sum_both")
print(s(6,5))
posted @ 2021-06-13 12:47  酒剑仙*  阅读(257)  评论(0)    收藏  举报