反射的四种用法

反射的总结:

就是通过字符串来获取, 删除和设置对象的属性或方法

反射:反射是动态语言的一个重要特点,它允许你在运行时检查对象的属性和方法,以及修改它们。这为元编程和编写通用代码提供了支持。

什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

python面向对象中的反射:

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

用户输入一段字符串, 执行该字符串对应的方法

其中前两点hasattr和getattr这两种方法并用

# 四个可以实现自省的函数
# hasattr()		# 判断一个属性是否在对象中; 返回True或False
# getattr()		# 通过字符串获取属性或方法; 如果获取到了,就返回相应的属性或方法
# setattr()		# 通过字符串来设置属性或方法
# delattr()		# 通过字符串来删除属性或方法

class Foo:
    def run(self):
        print("run")
    
    def speak(self):
        print("speak")
        
f = Foo()
cmd = input("请输入命令:")
# 返回内存地址
# print(Foo.__dict__[cmd])

# 方案一:
# Foo.__dict__[cmd]()

# 方案二: 通过反射来实现
if hasattr(f, cmd):
    run = getattr(f, cmd)
    run()
else:
    print("该命令不存在!")

另外两种方法setattr和delattr

setattr;

class Foo:
    def run(self):
        print("run")
    
    def speak(self):
        print("speak")
      
f = Foo()

# 通过用户输入key和value往对象中赋值
key = input("请输入key:")
value = input("请输入value:")
# 原始
# f.key=value

# 反射
setattr(f, key, value)
print(f.age)		# key输入什么就说写什么, 这里代码比较死

动态的往对象中放方法

class Foo:
    def run(self):
        print("run")
    
    def speak(self):
        print("speak")
      
f = Foo()

# 动态的往对象中放方法
def test(a):
    print(a)
    
# 没添加前
print(f.__dict__)
# 添加后
setattr(f, 'test', test)
print(f.__dict__)
# 调用
f.test(666)

动态的往对象中删除放法

class Foo:
    def run(self):
        print("run")
    
    def speak(self):
        print("speak")
      
f = Foo()

# 原始删除方法
# f.name='nick'
# print(f.__dict__)
# del p.name
# print(f.__dict__)

# 动态的删除属性
# 动态删除f中的属性为变量a的属性
f.name='nick'
f.age=18
f.sex='male'
# 查看删除前的属性
print(f.__dict__.keys())

a = input("请输入要删除的属性:")
# 直接f.a删除是不对的
# del f.a
delattr(f, a)
# 查看删除后的属性
print(f.__dict__.keys())

例子总结

class BlackMedium:
    feature='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
    def rent_house(self):
        print('%s 黑中介租房子啦,傻逼才租呢' %self.name)

b1=BlackMedium('万成置地','回龙观天露园')

#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))

获取属性 : getattr

# 如果第二个参数是属性则返回,属性对应的值 feature='Ugly'
n = getattr(b1, 'name')
print(n)
# 如果第二个参数是方法则返回,方法对应的内存地址,然后加括号调用
func = getattr(b1, 'sell_house')
func()
# getattr(b1,'aaaaaaaa') # 这里本来会报错, 但是我把第三个参数(默认值)改为字符串类型的('不存在啊!')就不会报错
print(getattr(b1, 'aaaaa', '不存在啊!'))

设置属性 : setattr

setattr(b1, 'my', True)
# 这里放置了一个匿名函数,不是绑定方法;调用的话有几个值就要传几个值
setattr(b1, 'my_gift', lambda self:self.name+'my')
print(b1.__dict__)
print(b1.my_gift(b1))

setattr的重点

setattr 函数允许你在运行时动态设置对象的属性值。这是非常有用的,因为它允许你根据需要配置对象属性,而不必在代码中硬编码这些属性。

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

# 创建一个 Person 实例
p = dafen("Alice")

# 动态添加属性并设置其值
xueke = input("请输入课程名字:")
cj = input("请输入得分成绩:")
xueke2 = '数学'
cj2 = 102
setattr(p, xueke, cj)
setattr(p, xueke2, cj2)

if hasattr(p, xueke):
    xueke = getattr(p, xueke)
    print(xueke)

# 动态的删除你输入的属性
shanchu = input("请输入你要删除的学科:")
delattr(p, shanchu)
# 访问动态添加的属性
print(f"你{xueke}的成绩为{getattr(p, xueke)}")

删除属性 : delattr

delattr(b1, 'abbr')
delattr(b1, 'my_gift')
# 如果没有该方法,则报错
delattr(b1, 'wo_diu')
print(b1.__dict__)

类和模块都可以用

posted @   hanyingshuo  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示