反射

导入模块常见的几种形式

1 def f1():
2     print("F1")
3 
4 def f2():
5     print("F2")
test1
1 import test1
2 test1.f1()
3 
4 from test1 import f1
5 f1()
6 
7 from test1 import f1 as new_f1
8 new_f1()
test

如何用字符串来导入模块呢,这里我们需要内置函数__import__

#根据字符串导入模块
c = __import__("test1")
c.f1()
#如果要导入from foo import base该如何操作呢?
b = __import__('foo.base')
print(b)
结果:
<module 'foo' from 'D:\\python_work\\elective_system\\foo\\__init__.py'>
#发现只导入到foo这里,这里我们需要加个fromlist参数
b = __import__('foo.base',fromlist=True)
print(b)
结果:
<module 'foo.base' from 'D:\\python_work\\elective_system\\foo\\base.py'>
此时就是我们想要结果了

不过官方建议用b = importlib.import_module("lib.base"),需先导入importlib模块。这句等同于__import__('foo.base',fromlist=True)

那么如何根据字符串在模块中寻找方法或则属性(这个是类的叫法,或则这里你可以叫全局变量和函数)呢?这里需要用到内置函数getattr

c = __import__("test1") #根据字符串导入模块
func = getattr(c,'f3') #根据字符串在模块中寻找函数
func()       #执行函数

#getattr还有第三个参数

c = __import__("test1")
getattr(c,"f3")
#如果模块中没有f3方法或则属性,则会报错

c = __import__("test1")
func = getattr(c,"f3",None)#加一个参数None
print(func)
结果:
None

如何判断一个属性或则方法是否存在?使用内置函数hasattr

c = __import__("test1")

print(hasattr(c,"f3"))
print(hasattr(c,"f1"))
结果:
False
True

应该还有设置属性或则方法,使用内置函数setattr

c = __import__("test1")

print(hasattr(c,"f3"))
setattr(c,"f3","F3")
print(hasattr(c,"f3"))
结果:
False
True

删除属性或则方法,使用内置函数delattr

c = __import__("test1")

print(hasattr(c,"f1"))
delattr(c,"f1")
print(hasattr(c,"f1"))
结果:
True
False 

上面这些就是反射的用法,反射的定义就是通过字符串映射或修改程序运行时的状态、属性、方法

在类中的使用

def sleep(self):
    print("%s is sleeping"%self.name)

class Role(object):

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

    def eat(self):
        print("%s is eating..."%self.name)

    def run(self):
        print("%s is runing..."%self.name)

d = Role("lxj")  #实例化
choice = input(">>").strip()  #输入方法

if hasattr(d,choice):  #判断属性或则方法是否存在

    func = getattr(d,choice)  #获得属性或则方法,属性直接返回值,方法返回是内存地址
    if callable(func):   #判断是否可调用
        func()    #方法调用
    else:
        print(func)
else:
    # setattr(d,choice,sleep)   #设置一个方法
    # d.sleep(d)

    setattr(d,choice,27)     #设置一个属性
    print(getattr(d,choice))

  

  

 

posted @ 2017-06-26 19:46  zj-luxj  阅读(126)  评论(0编辑  收藏  举报