- 在理解反射前,我们首先明白python是一门动态强类型的解释语言;
- 动态是什么?
-
# 没有类型声明,因为'1'是字符串,所以str是字符串,这就是动态 str='1' # 而其他语言,有类型声明的,比如java,因为str声明是字符串,所以'1'只能是字符串,这就是静态 String str = "1"; # 进一步理解动态 # 定义func时,func并不知道传入的对象是什么类型 def func(obj): return obj # 只有当调用func的时候,func才知道传进来的对象类型,这就是动态,也就是定义时没有声明类型,执行时才知道是什么类型 func(str)
- 强类型是什么?
-
# 1.先定义类型再使用 str='1' # 2.定义后类型不能随意切换,否则会报TypeError sum1=str+2 # 不能随意切换,不是不能切换,所以将字符串转为int类型,其实就是重新定义了类型 sum2=int(str)+2 print(sum2)
反射的概念:动态获取对象属性,动态获取对象方法
反射的体现:getattr()/setattr()/hasattr()
动态获取对象属性:
import math
attr = 'pi'
value = getattr(math, attr)
print(value) # 3.141592653589793
func = 'sqrt'
method = getattr(math, func)
result = method(2)
print(result) # 1.4142135623730951
动态获取对象方法:
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
print('Hello, {}'.format(self.name))
p = Person('Alice')
attr = 'name'
value = getattr(p, attr)
print(value) # Alice
method = 'say_hello'
func = getattr(p, method)
func() # Hello, Alice
2023-11-13 补充:
- 反射适用对象:模块,类;
- 反射通常使用getattr()实现;
- dir()可以拿到类或实例所有属性和值(包含父类继承),__dict__只能拿到实例的属性和值。
2023-12-18 补充:
通过反射拿到数据库存储的函数名称
import importlib
import sys
# 将项目根目录名称和文件运行路径进行拼接后,追加到系统环境变量中,避免导入模块的时候报错不存在
sys.path.append(os.path.join(os.getcwd(),"项目根目录名称"))
function_entrance=r"caedb/aa_cwis/test.py%function"
module_name,function_name=function_entrance.split("%")
# 相当于import module_name
module=importlib.import_module(module_name)
# 通过反射动态获取模块对象的函数属性的引用
function_object=getattr(module,function_name)
# 调用函数
function_object()
2024-07-09 补充:
反射的概念:
1.动态获取及修改类的属性;
2.动态调用类的方法.