Python反射类型判断

Python中类型判断

  • type
  • from types import MethodType, FunctionType

types python内置模块

Python3 中类型判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
types.BuiltinFunctionType               
types.BuiltinMethodType # 内置函数的类型,如len()或sys.exit(),以及内置类的方法。(这里,“内置”的意思是“用C写”。)
types.CodeType # 通过compile()返回的代码对象类型。
types.DynamicClassAttribute
types.FrameType # 框架对象的类型,如在tb中发现的。tb_frame如果tb是一个traceback对象。
types.FunctionType
types.GeneratorType # 由生成器函数创建的generator - iterator对象类型。
types.GetSetDescriptorType # 用PyGetSetDef(如FrameType)在扩展模块中定义的对象的类型。
types.LambdaType # 由lambda表达式创建的用户定义函数和函数的类型。
types.MappingProxyType
types.MemberDescriptorType
types.MethodType # 用户定义类实例的方法类型。
types.ModuleType
types.SimpleNamespace
types.TracebackType # traceback对象的类型,如sys.exc_info()
types.new_class
types.prepare_class

Dynamic type creation and names for built-in types

Typical use of these names is for isinstance() or issubclass() checks.

isinstance

这个真的鲜为人知, 我们可以用 isinstance(x, (float, int)) 来判断 x 是不是数:

1
2
3
4
5
6
>>> isinstance(1, (float, int))
True
>>> isinstance(1.3, (float, int))
True
>>> isinstance("1.3", (float, int))
False

那么对于第三个测试,你把 str 加入元组就可以看到这是怎么回事了:

1
2
>>> isinstance("1.3", (float, int, str))
True

也就是那个元组里面是 的关系,只要是其中一个的实例就返回 True

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A:
def __init__(self, name):
self.name = name


class B(A):
def __init__(self):
print("class B")


instance_A = A('baozi')
instance_B = B()

print(isinstance(instance_B, A))
print(instance_A.name)
print(type(instance_A) is A)
print(type(instance_B) is A)

# 执行结果
class B
True
baozi
True
False


isinstance(b, A) # 检测的是对象是不是某一个类 及父类的 对象

(type(b) is B) # 检测的是对象是不是某一个类的实例

反射

使用字符串的方式,操作对象的属性(对象属性,类的动态属性(方法))

某个命名空间中的某个 ‘变量名’ , 获取这个变量名对应的值

getattr(命名空间,’key’) == 命名空间.key
所有的a.b 都可以被反射成 getattr(a,’b’)

  • hasattr(obj, str) 判断对象中是否包含xxxx(str). **

  • getattr(obj, str) 从对象中获取xxx(str) **

    get表⽰示找, attr表⽰示属性(功能).

  • setattr(obj, str, value) 把对象中的str设置成valueo. # obj.str = value

  • delattr(obj, str) 从对象中删除xxxx(str) # del obj.str

类\对象\模块 实际上都是有自己的命名空间 ,从这个命名空间中获取某个值或者函数…名字
如果这个名字字符串数据类型
值 = getattr(命名空间,’字符串类型名字’)
如果getattr的值是一个属性或者普通变量,那么直接得到结果
如果getattr的值是函数或者方法 获取的是内存地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from types import MethodType, FunctionType
import os, sys

def iscall(file_di):
# file_di = file_mdoe.__dict__
attr = input('arg>>')
if hasattr(file_di, attr):
type_valeus = getattr(file_di, attr)
if isinstance(type_valeus, (FunctionType)):
return type_valeus()

# isinstance 元祖可以使用多个参数
elif isinstance(type_valeus, (str, int, list, dict)):
return type_valeus

# 变量是不可调用 "__call__"
# elif not hasattr(type_valeus,'__call__') :

# print(type_valeus)


# print(iscall(te))
# __dict__

sys modules

反射本文件中的名字 反射全局变量的值(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 全局的
from sys import modules

a = 1
b = 2
lst = [1, 2, 3]
class Manager: pass
class Student: pass
class Teacher: pass

getattr(modules[__name__], 'Student')
identify = input('>>>').strip()
类 = getattr(modules[__name__], identify)
print(类)
对象 = 类()
print(对象)

# 这玩意是个字典,跟操作字典似得。
print(modules[__name__])

# getattr(modules[__name__],'全局变量名')
# 从当前文件中寻找全局变量对应的值/地址


# 执行结果

<module '__main__' from '/Users/toorl/PycharmProjects/A17task/day026/05反射.py'>