08-06 反射

知识储备: 动态语言与静态语言

"""
动态语言: 不需要去声明这个数据类型,只有在执行的时候去发现这个数据类型。 例如: age = 18 只有在执行的时候才知道age的值18是整型
    主要是动态语言就有反射机制。
静态语言: 定义变量的时候必须要给指定好你这个变量是什么类型。例如: var x int; 就明确指定x是int类型.
"""

一. 什么是反射?

"""
什么是反射?
    python是动态语言,而反射(reflection)机制被视为动态语言的关键。
    反射指得是在程序过程中可以"动态(不见棺材不落泪)"获取对象的信息. 而在Python中,反射指的是通过字符串来操作对象的属性
反射的作用:
    基于反射可以十分灵活地操作对象的属性. 比如: 将用户交互的结果反射到具体的功能执行
"""

二. 实现反射机制的步骤

""
知识储备: dir() # 可以查看某一个对象下可以有哪些属性. 返回属性列表, 值都是字符串类型.
"""


class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say(self):
        print('<%s:%s>' % (self.name, self.age))


obj = People('辣白菜同学', 18)
# 1. 先通过dir查看处某一个对象下可以有哪个属性.
print(dir(obj))  # [..., 'age', 'name', 'say']

# 2. 可以通过字符串反射到真正的属性上, 得到属性值
print(obj.__dict__[dir(obj)[-2]])  # 辣白菜同学

三. 四个内置函数的使用: 通过字符串来操作属性值

class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


obj = People('egon', 18, '男')
print(dir(obj))

# 1. 基本使用介绍
# 提示: 下面可以理解为拿到对象, 到dir反馈的属性列表中进行查询, 所以需要指定符串来进行判断. 如果是getattr(obj, '属性名')那么就会调用"obj.__dict__['属性名']"来获取到指定的属性名对应的属性值. (补充: 类也是对象, 这个功能也是可以正常使用)
"""
返回对象是否具有具有给定名称的属性。
这是通过调用getattr(obj, name)和捕获AttributeError来完成的。
"""
print(hasattr(obj, 'name'))  # True
print(hasattr(obj, 'NAME'))  # False
print(hasattr(obj, 'age'))   # True
print(hasattr(obj, 'sex'))   # True
print(hasattr(obj, '__init__'))  # True
print(hasattr(obj, 'People'))  # False
print(hasattr(obj, '__str__'))  # True


"""
getattr(object, name[, default]) -> value   
从对象中获取命名属性; getattr(x, 'y')等于x.y。
当给出默认参数时,当属性没有给出时,就返回默认参数存在; 没有它,在这种情况下就会引发异常。
"""
print(getattr(obj, 'name'))  # egon
# print(getattr(obj, 'EGON'))  # AttributeError: 'People' object has no attribute 'EGON'
print(getattr(obj, 'NAME', None))  # None

print(getattr(obj, 'age', '默认返回值'))  # 18
print(getattr(obj, 'AGE', '默认返回值'))  # 默认返回值

"""
将给定对象上的命名属性设置为指定值。
setattr(x, 'y', v)等于' x.y = v”
"""
setattr(obj, 'name', 'EGON')
print(getattr(obj, 'name'))  # EGON

"""
从给定对象中删除命名属性。
delattr(x, 'y')相当于'' del x.y'
"""
delattr(obj, 'name')
print(obj.__dict__)  # {'age': 18, 'sex': '男'}

# 2. 组合使用:
# 2-1. 判断对象中有没有这个属性, 再进行获取 hasattr --> getattr
if hasattr(obj, 'age'):
    print(getattr(obj, 'age'))  # 18
else:
    print("对不起, obj对象中没有age属性!")

# print(getattr(obj, 'age', None))  # 或者使用这种方式

# 2-2. 判断内置对象是否含有这个属性, 再进行设置 hasattr --> setattr
obj = 'x'
if hasattr(obj, 'x'):
    setattr(obj, 'x', 11111)
else:
    print('对不起, obj对象这个内置属性不能进行设置!')


# 3. 运用示例:
class Ftp:
    def put(self):
        print("正在执行put功能!")

    def get(self):
        print("正在执行get功能!")

    def interactive(self):
        while True:
            method = input("输入命令: ").strip()
            if hasattr(self, method):
                getattr(self, method)()
            else:
                print("输入的指令不存在")
obj = Ftp()
obj.interactive()
posted @ 2020-04-15 17:29  给你加马桶唱疏通  阅读(127)  评论(0编辑  收藏  举报