反射
【一】概要
- 在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())