面相对象之反射

面相对象之反射

一、什么是反射

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

二、反射方法

[1]四种反射方法

  1. 获取对象的属性值,如果属性值不存在可以设定默认值
    • getattr(object, name[, default])
  2. 判断对象是否具有指定属性
    • hasattr(object, name)
  3. 设置对象的属性值
    • setattr(object, name, value)
  4. 删除对象的属性
    • delattr(object, name)

[2]放射方法的使用

(1)获取对象的属性值,如果属性值不存在可以设定默认值

  • getattr(object, name[, default])
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


people = Person('Xanadu', 22)
print(getattr(people, 'name', None))  # Xanadu
print(getattr(people, 'age', None))  # 22
# 设定了默认值之后取不到值会返回默认值
print(getattr(people, 'sex', None))  # None

(2)判断对象是否具有指定属性

  • hasattr(object, name)
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


people = Person('Xanadu', 22)
# 有相应属性返回True
print(hasattr(people, 'name'))  # True
print(hasattr(people, 'age'))  # True
# 无相应属性返回False
print(hasattr(people, 'sex'))  # False

(3)设置对象的属性值

  • setattr(object, name, value)
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


people = Person('Xanadu', 22)
# 有相应属性修改相应属性
setattr(people, 'name', 'bridge')
print(people.name)  # bridge
setattr(people, 'age', 18)
print(people.age)  # 18
# 没有相应属性就添加相应属性
setattr(people, 'sex', 'male')
print(people.sex)  # male

(4)删除对象的属性

  • delattr(object, name)
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


people = Person('Xanadu', 22)

print(people.age)  # 22
delattr(people, age)
print(people.age)  # NameError: name 'age' is not defined

三、拓展

(1)类也是对象

class Student(object):
    school = '希望小学'

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

    def attend_class(self):
        print(f'{self.name}可以上课。')


# 类中的数据属性和函数属性也可以使用反射方法进行判断等操作
print(hasattr(Student, 'school'))  # True
print(hasattr(Student, 'name'))  # False
print(hasattr(Student, 'attend_class'))  # True

(2)反射当前模块成员

import sys


def func_1():
    ...


def func_2():
    ...


there_module = sys.modules[__name__]

print(hasattr(there_module, 'func_1'))  # True
print(getattr(there_module, 'func_2'))  # <function func_2 at 0x00000247A9AB28C0>

四、反射的好处

  • 反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,意味着可以在程序运行过程中动态地绑定接口的实现。
  • 这种灵活性使得程序更容易扩展和维护。
  • 大白话就是可以在使用接口前判断接口是否存在并执行不同的后续代码
class MainInterface(object):
    def run(self):
        ...


class Interface1(MainInterface):
    def run(self):
        print('执行接口一')


class Interface2(MainInterface):
    def run(self):
        print('执行接口二')


def run_interface(interface):
    interface.run()


interface_input = input("请输入想要实现的接口:")

# 从全局名称空间中获取接口名字对应的类
interface_class = globals().get(interface_input)

# 判断是否存在该接口
if interface_class and issubclass(interface_class, MainInterface):
    run_interface(interface_class())
else:
    print('接口不存在')


'''
请输入想要实现的接口:Interface2
执行接口二
'''
'''
请输入想要实现的接口:111
接口不存在
'''
posted @ 2024-01-29 14:44  桃源氏  阅读(19)  评论(0)    收藏  举报