Python反射机制详解:getattr、setattr与delattr实战
本文深入解析Python反射机制,通过getattr、setattr和delattr三个核心函数演示如何动态获取、添加及删除对象属性与方法。重点剖析setattr添加方法的本质是绑定外部函数引用,以及delattr对动态方法删除的限制,帮助开发者掌握运行时状态修改技巧。
反射机制允许程序在运行时通过字符串名称来映射、修改或访问对象的状态、属性及方法。实现这一功能主要依赖以下四种核心操作方式。
''' 使用getattr(object, name_str, default=None) 方法获取object对象里 对应的方法或者属性的内存地址 如果是属性:直接返回属性值 如果是方法:返回方法的内存地址 ''' # hasattr(object,name_str) 判断object对象是否有一个名为name_str的方法或者属性
具体代码实现如下所示:
# -*- coding:utf8 -*-
class Person(object):
def __init__(self, name):
self.name = name
def fun(self):
print("%s正在玩耍" % self.name)
p1 = Person("某人飞")
name_str = input("请输入方法或者属性").strip()
# hasattr(object,name_str) 判断object对象是否有一个名为name_str的方法或者属性
if hasattr(p1, name_str):
'''
如果有就可以使用getattr(object, name_str, default=None) 方法获取object对象里
对应的方法或者属性的内存地址
如果是属性:直接返回属性值
如果是方法:返回方法的内存地址
'''
print(getattr(p1, name_str , 80))
# >>>name: 某人飞
# >>>fun : <bound method Person.fun of <__main__.Person object at 0x0000020B76A81370>>
# 所以如果是方法,那么可以这么处理
a = getattr(p1, name_str)
a()
else:
print("该对象没有这些属性和方法")
判断和获取的演示
若目标对象中不存在通过键盘输入指定的方法,可以利用setattr函数为该对象动态添加一个方法。
def bulk(self):
print("这是在%s对象的类外部创建的方法"%self.name)
class Person(object):
def __init__(self, name):
self.name = name
def fun1(self):
print("%s正在玩耍" % self.name)
p1 = Person("某人飞")
name_str = input("请输入您的方法或者属性").strip()
if hasattr(p1, name_str):
a = getattr(p1, name_str)
a()
else: #如果没有这个方法,那么为其创建一个已经存在的方法
"""
setattr(p1, name_str, bulk)
为对象p1添加一个已经存在的bulk的方法,命名为name_str
"""
setattr(p1, name_str, bulk)
a = getattr(p1, name_str)
a(p1)
"""
运行结果
请输入您的方法或者属性ui
这是在某人飞对象的类外部创建的方法
"""
setattr(p1, name_str, bulk)添加方法
若目标对象中不存在通过键盘输入指定的属性,同样可以使用setattr函数为该对象动态添加一个属性。
class Person(object):
def __init__(self, name):
self.name = name
p1 = Person("某人飞")
name_str = input("请输入您的方法或者属性").strip()
if hasattr(p1, name_str):
a = getattr(p1, name_str)
print(a)
# 也可以同setattr修该已有属性的值
setattr(p1, name_str, "飞")
print(p1.name)
else: #如果没有这个属性,那么为其添加一个属性 ,并为其设置一个默认值20
setattr(p1, name_str, 20)
a = getattr(p1, name_str)
print(a)
"""
运行结果:
请输入您的方法或者属性name
某人飞
飞
运行结果:
请输入您的方法或者属性age
20
"""
setattr(p1, name_str, index)添加属性
尝试删除对象中的属性和方法,但需注意,delattr实际上无法直接删除对象原本定义的方法。
class Person(object):
def __init__(self, name):
self.name = name
def fun(self):
print("这是一个实例方法")
p1 = Person("某人飞")
name_str = input("请输入您的方法或者属性").strip()
if hasattr(p1, name_str):
# 删除这个对象的属性或者方法
delattr(p1, name_str)
else:
pass
print(p1.name)
p1.fun()
"""
运行结果:
请输入您的方法或者属性name
AttributeError: 'Person' object has no attribute 'name'
运行结果:
请输入您的方法或者属性fun
AttributeError: fun
"""
delattr(p1, name_str)只能删除属性,和动态添加的方法
需要特别注意:虽然delattr可以删除通过setattr动态添加的方法,但这其实是一种表象。真相是,setattr添加方法并非真正向对象内部注入方法逻辑,而是添加了一个属性,该属性的名称由setattr的第二个参数指定,其值则指向外部函数的引用地址。因此,调用该对象的属性时,实际上是间接调用了外部函数,从而产生对象拥有方法的假象。本质上,setattr和delattr均仅针对对象的属性进行操作,无法直接作用于对象原本定义的方法。
至此,关于Python反射机制的知识点介绍完毕。如需了解更多Python反射相关内容,建议查阅本站过往文章或继续浏览后续教程,感谢大家的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









