面向对象之反射运用

先看下hasattr和getattr在反射中的用法

import sys


class apache(object):
    def __init__(self, tcp):
        self.tcp = tcp

    def start(self):
        print("apache is starting,host id is [%s]" % self.tcp)

    def stop(self):
        print("apache is stoping,host id is [%s]" % self.tcp)

    def restart(self):
        self.stop()
        self.start()


if __name__ == '__main__':
    server = apache("333")
    if hasattr(server, "start"):  # 判断实例中是否有ays.argv[1]这个方法
        func = getattr(server, "start")  # 获取server.sys.argv[1]方法的内存地址
        func()  # 执行server.sys.argv[1]这个方法

再看下setattr在反射中的运用

import sys


class apache(object):
    def __init__(self, tcp):
        self.tcp = tcp
        print(tcp)

    def start(self):
        print("apache is starting,host id is [%s]" % self.tcp)

    def stop(self):
        print("apache is stoping,host id is [%s]" % self.tcp)

    def restart(self):
        self.stop()
        self.start()


def test_run(name):
    print("running", name)


if __name__ == '__main__':
    server = apache("333")
    setattr(server, "run", test_run)  # 相当于:server.run = test_run 赋值操作,这一步操作之后那么test_run函数就属于apache类
    # 我们可以看到,本来server这个实例本身是没有test_run这个方法的,且test_run和apache这个类根本就没有任何关系,但是我们通过setattr方法,就可以把外面的函数赋值给
    # 某个实例,比如这里的例子,我们就把函数test_run的内存地址赋值给了server.run,也就是说test_run == server.run
    # 注意,这里只绑定到server这实例上,其他实例还是不能用test_run这个方法的
    server.run("alex")  # 这里其实调用的是test_run这个方法


# 上面的例子中,在test_run中不能使用实例变量,我们可以通过下面的方法就可以实现test_run函数可以调用实例变量

# 定义函数需要按照下面的格式来定义
def test_run(self, name):
    print("running", name, self.tcp)


if __name__ == '__main__':
    server = apache("333")
    setattr(server, "run", test_run)
    # 调用的时候需要这样调用
    server.run(server, "alex")

最后看下delattr在反射中的运用

import sys


class apache(object):
    def __init__(self, tcp):
        self.tcp = tcp

    def start(self):
        print("apache is starting,host id is [%s]" % self.tcp)

    def stop(self):
        print("apache is stoping,host id is [%s]" % self.tcp)

    def restart(self):
        self.stop()
        self.start()


if __name__ == '__main__':
    server = apache("1000")
    # delattr(server,"stop")
    # server.stop()

    # 这样的写法是错误的,因为stop这个方法不属于对象,而属于类,所以删除对象中的stop方法肯定是不可以的
    print(server.tcp)
    # 1000
    # delattr(server,"tcp")
    # print(server.tcp)
    # 所以如果我们删除对象的话,只能删除对象的变量,上面这个例子,我们就可以删除对象中的变量,然后在打印就发现没有这个值了

    # 所以如果要删除方法,那么我们只能删除类的方法,而不能删除对象的方法,因为方法都是属于类的

    # 在删之前我们先判断一下对象中是否有stop这个方法
    if hasattr(apache, "stop"):
        print(True)
    else:
        print(False)

    # True  结果证明有stop这个方法

    # 在删之后我们在判断一下对象中是否有stop这个方法
    delattr(apache, "stop")
    if hasattr(apache, "stop"):
        print(True)
    else:
        print(False)
    # False 结果证明没有stop这个方法

 

posted @ 2018-10-14 21:50  小黑_9527  阅读(175)  评论(0编辑  收藏  举报