Python进阶之反射

【一】什么是反射

  • 反射是一种程序可以访问、检测和修改其本身状态或行为的能力
  • 在 Python 中,反射主要指通过字符串的形式操作对象的属性
  • python中的一切事物都是对象,都可以使用反射

【二】反射方法

  • getattr(object, key):获取对象的属性值,如果属性不存在,可提供默认值
  • hasattr(object, key):判断对象是否具有指定属性
  • setattr(object, key, value):设置对象的属性值和属性名
  • delattr(object, key):删除对象的属性

【三】反射方法的使用

(1)getattr

class Student(object):
    school = '北京大学'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def read(self):
        print(f"{self.age}岁的学生{self.name}的学校是{self.school}")


student = Student('ligo', 18)
#(1)数据属性:在对象中映射数据属性的时候,如果对象中存在当前属性值则直接将属性值拿出来
res = getattr(student, 'name')
print(res)  # ligo
res = getattr(student, 'age')
print(res)  # 18

#(2)函数属性:在对象中映射函数属性的时候,如果对象中存在当前属性名对应的数据属性
# 则直接获取当前函数属性的内存地址,可以直接调用当前函数
res = getattr(student, 'read')
print(res)  # <bound method Student.read of <__main__.Student object at 0x000001E0425549D0>>
res()  # 18岁的学生ligo的学校是北京大学

#(3)如果对象中不存在当前属性名对应的属性,会直接报错
res = getattr(student, 'sex')
print(res)  # AttributeError: 'Student' object has no attribute 'sex'

(2)hasattr

class Student(object):
    school = '北京大学'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def read(self):
        print(f"{self.age}岁的学生{self.name}的学校是{self.school}")


student = Student('ligo', 18)
# (1)数据属性:如果对象中存在当前属性值,则返回True
res = hasattr(student, 'name')
print(res)  # True
res = hasattr(student, 'age')
print(res)  # True

# (2)函数属性:如果对象中存在当前属性名对应的数据属性,则返回True
res = hasattr(student, 'read')
print(res)  # True

# (3)如果对象中不存在当前属性名对应的属性,则返回False
res = hasattr(student, 'sex')
print(res)  # False

(3)setattr

class Student(object):
    school = '北京大学'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def read(self):
        print(f"{self.age}岁的学生{self.name}的学校是{self.school}")


def outer_read():
    print("outer_read")


student = Student('ligo', 18)
# (1)数据属性:向对象中设置属性名和属性值,如果对象中存在当前属性则直接替换,否则新增
res1 = setattr(student, 'name', 'scott')
print(student.name)  # scott
res2 = setattr(student, 'sex', '男')
print(student.sex)  # 男

# (2)在对象中映射函数属性的时候,如果对象中存在当前属性名对应的数据属性,则返回True
print(setattr(student, 'outer_read', outer_read))  # None
print(hasattr(student, 'outer_read'))  # True
print(getattr(student, 'outer_read'))  # <function outer_read at 0x000002B5DFECA7A0>
getattr(student, 'outer_read')()  # outer_read

(4)delattr

class Student(object):
    school = '北京大学'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def read(self):
        print(f"{self.age}岁的学生{self.name}的学校是{self.school}")


student = Student('ligo', 18)
# (1)数据属性:在对象中删除数据属性的时候,如果对象中存在当前属性值则直接删除
print(hasattr(student, 'name'))  # True
delattr(student, 'name')
print(hasattr(student, 'name'))  # False

# (2)在对象中删除函数属性的时候,要根据参数是对象还是类来做区分
print(hasattr(Student, 'read'))  # True
# 如果参数是当前对象,则无法删除函数属性
# res = delattr(student, 'read')
# 如果参数是当前类,则可以删除函数属性
delattr(Student, 'read')
print(hasattr(Student, 'read'))  # False

# (3)如果对象中不存在当前属性名对应的属性,则直接报错
print(delattr(student, 'sex'))  # AttributeError: sex
posted @ 2024-05-10 18:45  Ligo6  阅读(82)  评论(0)    收藏  举报