Python面向对象之反射

反射

【一】概要

  • 在Python中,反射指的是通过字符串来操作对象的属性,涉及四个内置函数的使用(Python中一切皆对象,类和对象都可以用)

【二】常用方法

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

【三】详解

【1】getattr(object, name[, default]):获取对象的属性值

  • 源码解释
"""
    getattr(object, name[, default]) -> value
    
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
"""

  • 代码解释
class Person:
    eyes = 2

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

        
'''实例化对象'''
p = Person('user', 20)

res = getattr(p, 'eyes')
res1 = getattr(p, 'name')
print(res)  # 2
print(res1)  # user

'''如果是不存在的属性,且不指定默认值,将会报错'''
# res2 = getattr(p,'gender')
# print(res2)   # AttributeError: 'Person' object has no attribute 'gender'

'''设置默认值'''
res3 = getattr(p, 'gender', 'male')
print(res3)  # male   # 可以拿到默认值
print(p.__dict__)   # {'name': 'user', 'age': 20}   # 但是并不会添加到名称空间中

res4 = getattr(p, 'name', '001')   # 如果属性已经存在,将拿到原本的数据
print(res4)  # user
'''getattr的函数用法'''
class Person:
    eyes = 2

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

    def func(self):
        print('from func')

    def func_exists(self):
        print('from func_exists')


p = Person('user', 20)
res = getattr(p, 'func')  # 可以通过getattr来获取函数内存地址调用
print(res)  # <bound method Person.func of <__main__.Person object at 0x000001D4A96CB910>>
res()  # from func

'''函数用法2:可以将不存在的函数名,通过指定内存地址,打印出'''
res1 = getattr(p, 'func_not', p.func_exists)
print(res1)  # <bound method Person.func_exists of <__main__.Person object at 0x000002EA0BA0B910>>
res1()  # from func_exists

  • 应用场景
class School(object):
    def fault(self):
        print("from fault")

    def not_fault(self):
        print("cant fund func")


s = School()
s.fault()
'''当调用一个不存在的属性时,正常调用将会报错'''
# s.true()  # AttributeError: 'School' object has no attribute 'true'
'''如果不存在,将会输出我们指定的内容'''
res = getattr(s, 'true', s.not_fault)
res()
'''如果存在,将正常的输出函数'''
res1 = getattr(s, 'fault', s.not_fault)
res1()  # from fault

【2】hasattr(object, name):判断对象是否具有指定属性

  • 源码解释
"""
Return whether the object has an attribute with the given name.

This is done by calling getattr(obj, name) and catching AttributeError.
"""
  • 代码解释
'''返回布尔值'''
class School(object):
    def func(self):
        print("from func")


s = School()
res = hasattr(s, 'func')
print(res)  # True
res1 = hasattr(s, 'index')
print(res1)  # False

【3】setattr(object, name, value):设置对象的属性值

  • 源码解释
"""
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
  • 代码解释
class School(object):
    def func(self):
        print("from func")


def index():
    print("from outer func.index")


s = School()
'''如果已经存在,将会替换'''
res = setattr(s, 'func', 'func.index')  # 替换成字符串'func.index'
print(res)  # None # 没有返回值
'''如果不存在,将会新增'''
setattr(s, 'index', index)  # 新增一个函数
print(s.__dict__)
# {'func': 'func.index', 'index': <function index at 0x0000026360D73EB0>}
s.index()  # from outer func.index

【4】delattr(object, name):删除对象的属性

  • 源码解释
"""
Deletes the named attribute from the given object.

delattr(x, 'y') is equivalent to ``del x.y''
"""
  • 代码解释
class School(object):
    name = 'school'

    def func(self):
        print("from func")


print(School.name)# school
School.func(self=School())  # from func
print(School.__dict__)
# {'__module__': '__main__', 'name': 'school', 'func': <function School.func at 0x00000138D71027A0>, ...}

'''删除属性值'''
delattr(School, 'name')
delattr(School, 'func')
print(School.__dict__)
# {'__module__': '__main__', ...}

'''调用删除后的值,将会报错'''
print(School.name)   # AttributeError: type object 'School' has no attribute 'name'
School.func(School())
posted @ 2024-01-15 10:19  Lea4ning  阅读(14)  评论(0编辑  收藏  举报