首页 > 代码库 > ##.Python自学之路:反射(非常重要的编程思路)

##.Python自学之路:反射(非常重要的编程思路)

反射的意义:通过字符串获取一个类的方法的内存地址,并调用该方法。

  格式:if hasattr(self, ‘anAttr‘)

        func = getattr(self, ‘anAttr‘)  #获取内存地址

        func()                                    #调用该方法,等价于anAttr()

     setattr(x, ‘y‘, v)

     delattr(x, ‘y‘)

看下面这个例子

技术分享

版本一:效率低下,若类WebServer中的方法多个上百,那么主函数中的if语句就要判断上百次。

 

import sys

class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port
    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

if __name__ == "__main__":
    server = WebServer(localhost ,333)
    print(sys.argv[1])   #执行脚本时的第一个参数
    if sys.argv[1] == start:
        server.start()
    elif sys.argv[1] == stop:
        server.stop()
    elif sys.argv[1] == restart:
        server.restart()

 

版本二:引入字典的思想,不过还是存在代码重用的现象,还可以继续改进

 

技术分享

import sys

class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port
    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

if __name__ == "__main__":
    server = WebServer(localhost ,333)
    print(sys.argv[1])
    cmd_dic = {
        start: server.start,
        stop: server.stop,
    }
    if sys.argv[1] in cmd_dic:
        cmd_dic[sys.argv[1]]()

 

版本三:引入反射

 

技术分享

import sys

class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port
    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

if __name__ == "__main__":
    server = WebServer(localhost ,333)
    print(sys.argv[1])
    if hasattr(server, sys.argv[1]):
        func = getattr(server, sys.argv[1]) #获取server.start 的内存地址
        func()  #等价于server.start()

 

反射方法之setattr

技术分享

import sys

class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port
    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

def testRun(ins, name):  #该方法并不是类的方法哦,但是可以用set绑定到实例中去
    print("running....",name,ins.host) #ins相当于self

if __name__ == "__main__":
    server = WebServer(localhost ,333)
    server1 = WebServer(localhost1, 666)
    print(sys.argv[1])
    #setattr(x, ‘y‘, v) is equivalent to x.y = v
    setattr(server, run, testRun) #给实例server绑定了testRun,重命名为run
    server.run(server, wuwen) #将server传给ins(实例)
    server1.run(server, wuwen)

 

反射方法之delattr

class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port
    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

if __name__ == "__main__":
    server = WebServer(localhost ,333)
    delattr(server, stop) #错误写法,实例无法参数类中的方法
    print(server.host)
    delattr(server, host) #删除参数实例中的属性host
    print(server.host)
    delattr(WebServer, restart) #删除参数类中的restart方法
    print(server.restart())

 

##.Python自学之路:反射(非常重要的编程思路)