相关文档
动态生成函数
https://www.cnblogs.com/olivetree123/p/5067685.html
介绍
自省和反射是两个比较专业化的术语,首先自省是获取对象的能力,而反射是操纵对象的能力。
Python中关于反射与自省的部分方法 | |
---|---|
常用方法 | |
dir() | 返回一个列表,存储该对象下能被 . 出的所有属性与方法。 |
hasattr() | 查看对象是否具有某种属性或方法,返回True或者False。 |
getattr() | 获取对象下的某一属性或方法。如被获取对象没有相应的属性或方法,则可以为其设置默认值。 |
setattr() | 设置对象下的某一属性的值,通常我们不会在对象外部为其新增某一方法,而是在在对象的类中进行设置。 |
delattr() | 删除对象中的某一属性或方法。 |
其他的一些方法 | |
compile() | 函数将一个字符串编译为字节代码。 |
help() | 获取对象的帮助信息,注意。没有返回值!内部会调用print()进行打印操作。 |
issubclass() | 判断一个类是不是另一个类的子类 |
isinstance() | 判断一个对象是否是一个已知的类型 |
id() | 返回存储对象的内存地址编号 |
callable() | 判断对象是否可调用 |
使用示例
编译相关
编译compile()
入参
- source — 字符串或者AST(Abstract Syntax Trees)对象。。
- filename — 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。
- mode — 指定编译代码的种类。可以指定为 exec, eval, single。
- flags — 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。。
- flags和dont_inherit是用来控制编译源码时的标志
>>>str = "for i in range(0,10): print(i)"
>>> c = compile(str,'','exec') # 编译为字节代码对象
>>> c
<code object <module> at 0x10141e0b0, file "", line 1>
>>> exec(c)
0
1
2
3
4
5
6
7
8
9
>>> str = "3 * 4 + 5"
>>> a = compile(str,'','eval')
>>> eval(a)
17
模块相关
动态导入模块
modules = 'modules'
func = 'func'
obj = __import__(modules)
if hasattr(obj, func):
func = getattr(obj, func)
func()
类相关
判断class是否有这个方法或变量hasattr
class Person(object):
def __init__(self,name):
self.name = name
def talk(self):
print("%s正在交谈"%self.name)
p = Person("laowang")
print(hasattr(p,"talk")) # True。因为存在talk方法
print(hasattr(p,"name")) # True。因为存在name变量
print(hasattr(p,"abc")) # False。因为不存在abc方法或变量
获取class的方法或变量的内存地址getattr
class Person(object):
def __init__(self,name):
self.name = name
def talk(self):
print("%s正在交谈"%self.name)
p = Person("laowang")
n = getattr(p,"name") # 获取name变量的内存地址
print(n) # 此时打印的是:laowang
f = getattr(p,"talk") # 获取talk方法的内存地址
f() # 调用talk方法
s = getattr(p,"abc","not find")
print(s) # 打印结果:not find。因为abc在对象p中找不到,本应该报错,属性找不到,但因为修改了找不到就输出not find
class添加变量或方法setattr
def abc(self):
print("%s正在交谈"%self.name)
class Person(object):
def __init__(self,name):
self.name = name
p = Person("laowang")
setattr(p,"talk",abc) # 将abc函数添加到对象中p中,并命名为talk
p.talk(p) # 调用talk方法,因为这是额外添加的方法,需手动传入对象
setattr(p,"age",30) # 添加一个变量age,复制为30
print(p.age) # 打印结果:30