首页 > 其他分享 >反射的四种用法

反射的四种用法

时间:2023-10-30 11:45:42浏览次数:30  
标签:反射 name self def 用法 b1 print 四种 属性

反射的总结:

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

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

什么是反射

反射的概念是由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__)

类和模块都可以用

标签:反射,name,self,def,用法,b1,print,四种,属性
From: https://www.cnblogs.com/hanyingshuo/p/17797414.html

相关文章

  • issubclass和isinstance的用法
    issubclass(sub,super)判断第一个类是不是第二个类的的子类;是则返回True否则返回FalseclassFoo:passclassBar(Foo):pass#以元组的方式查看Bar类的所以父类print(Bar.__bases__)#这里做判断print(issubclass(Bar,Foo))print(issubclass(Foo,Bar))clas......
  • 关于mapStruct-高阶用法
    描诉:符合应用场景的实用的mapStruct对于bean映射的方法1.使用自定义转换器(Converters):如果你需要自定义映射逻辑,可以创建自定义转换器类,并使用@Mapper注解的uses属性来引用它们。这允许你在映射中使用自定义方法,以满足特定需求.@Mapper(uses={CustomConverter.class})public......
  • Java基础 反射获取构造方法
    在Java中,万物皆对象。比如,字节码文件可以看作是Class这个类的对象;Constructor这个类是用来描述构造方法的,所以这个类的对象就表示构造方法的对象;Field这个类是用来描述成员变量的,所以这个类的对象就表示成员变量的对象;Method 这个类是用来描述成员方法的,所以这个类的对......
  • Java基础 反射
     反射允许对封装类的字段(成员变量)、方法(成员方法)和构造函数(构造方法)的信息进行编程访问  获取字段(成员变量)、成员方法和构造方法的时候,我们不是从Java文件中获取的,而是从class字节码文件当中获取的所以我们首先要先学习如何获取class字节码文件的对象 ......
  • es查询script 用法
    在Elasticsearch中,可以使用脚本(Script)来执行自定义的逻辑和计算。脚本可以用于查询、过滤、排序等各种操作。下面是关于脚本使用语法的详细说明,并附上示例说明:脚本语言:Elasticsearch支持多种脚本语言,如Painless、Groovy等。但从Elasticsearch7.0版本开始,默认只支持Painless脚本语......
  • SQL多表联合查询用法介绍
    SQL多表联合查询用法介绍一、联合查询基本概念联合查询,又称为多表查询,是指针对两个或多个表进行查询,并将结果集合并起来展示的过程。在实际应用中,联合查询是很常见的查询方式,因为单张表无法满足复杂的查询需求。二、联合查询的语法联合查询的语法格式如下:SELECTcolumn1,co......
  • 列表包裹元组,指定元组中数字大小排序字段operator用法
    importoperatorsomelist=[(1,5,8),(6,2,4),(9,7,5)]somelist.sort(key=operator.itemgetter(0))print(somelist)#[(1,5,8),(6,2,4),(9,7,5)]somelist.sort(key=operator.itemgetter(1))print(somelist)#[(6,2,4),(1,5,8),(9,7,5)]somelist.sor......
  • 四种常见线程池的原理
    newFixedThreadPool(固定数目线程的线程池)newCachedThreadPool(可缓存线程的线程池)newSingleThreadExecutor(单线程的线程池)newScheduledThreadPool(定时及周期执行的线程池)前三种线程池的构造直接调用ThreadPoolExecutor的构造方法。newSingleThreadExecutorpublicsta......
  • multiset 用法
    头文件#include<set>代码#include<set>#include<iostream>usingnamespacestd;intmain(){ multiset<int>ms; ms.insert(1); ms.insert(5); ms.insert(5); ms.insert(5); ms.insert(2); ms.insert(1); for(autoiter=ms.be......
  • 深入理解Java IO流: 包括字节流和字符流的用法、文件读写实践
    (文章目录)......