Python面向对象之九:反射

Python面向对象之九:反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

一、什么是反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性。

python中的一切事物都是对象(都可以使用反射)。

二、对象的反射

1、getattr 获取指定字符串名称的对象属性
class Foo:
    f = '类的静态变量'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(f'hi,{self.name}')

obj = Foo('晴朗', 73)
n = getattr(obj, 'name')
print(n)  #晴朗
func = getattr(obj, 'say_hi')
func()  #hi,晴朗
print(getattr(obj, 'aaaaaaaa', '不存在啊')) #报错
2、hasattr 判断对象是否有对应的对象属性(字符串)
class Foo:
    f = '类的静态变量'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(f'hi,{self.name}')

obj = Foo('晴朗', 73)

#检测是否含有某属性
print(hasattr(obj, 'name'))     #True
print(hasattr(obj, 'say_hi'))   #True
print(hasattr(obj, 'aaabbb'))   #False
3、setattr 为对象设置一个对象属性
class Foo:
    f = '类的静态变量'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(f'hi,{self.name}')

obj = Foo('晴朗', 73)
setattr(obj, "ty", '帅哥')
setattr(obj, 'show_name', lambda self:self.name+'是帅哥')
print(obj.__dict__)  #{'name': '晴朗', 'age': 73, 'ty': '帅哥', 'show_name': <function <lambda> at 0x00000207559E7C10>}
print(obj.show_name(obj))  #晴朗是帅哥
4、delattr 删除指定属性
class Foo:
    f = '类的静态变量'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(f'hi,{self.name}')

obj = Foo('晴朗', 73)
delattr(obj, 'age')
# delattr(obj, 'say_hi')  #报错,不能删除方法
# delattr(obj, 'show_name111')#不存在,则报错
print(obj.__dict__)   #{'name': '晴朗'}

三、类的反射

class Foo(object):
    staticField = "old boy"

    def __init__(self):
        self.name = 'wupeiqi'

    def func(self):
        return 'func'

    @staticmethod
    def bar():
        return 'bar'

print(getattr(Foo, 'staticField'))
m = getattr(Foo, 'func')
print(m(object))
print(getattr(Foo, 'bar'))
setattr(Foo, 'ty', '帅哥')
print(Foo.ty)

# 运行结果:
# old boy
# func
# <function Foo.bar at 0x0000018D4DD77DC0>
# <class '__main__.Foo'> ty
# 帅哥

四、模块的反射

1 、当前模块的反射
import sys

def s1():
    print('s1')

def s2():
    print('s2')

this_module = sys.modules[__name__]

m = hasattr(this_module, 's1')
print(m)  #True
n = getattr(this_module, 's2')
print(n)  #<function s2 at 0x0000022C4F847CA0>
n()  #s2
2、其他模块的反射
#一个模块中的代码
def test():
    print('from the test')
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""
# 另一个模块中的代码
import module_test as obj

obj.test()  #from the test

print(hasattr(obj,'test')) #True

getattr(obj,'test')()  #from the test

四、反射的应用

例子:模拟网页登录

1、未用反射:

class User:
    def login(self):
        print('欢迎来到登录页面')

    def register(self):
        print('欢迎来到注册页面')

    def save(self):
        print('欢迎来到存储页面')


while 1:
    choose = input('>>>').strip()
    if choose == 'login':
        obj = User()
        obj.login()
        break

    elif choose == 'register':
        obj = User()
        obj.register()
        break

    elif choose == 'save':
        obj = User()
        obj.save()
        break
    else:
        print('输入错误,请重新输入!')

2、使用反射:

class User:
    def login(self):
        print('欢迎来到登录页面')
    
    def register(self):
        print('欢迎来到注册页面')
    
    def save(self):
        print('欢迎来到存储页面')

user = User()
while 1:
    choose = input('>>>').strip()
    if hasattr(user,choose):
        func = getattr(user,choose)
        func()
        break
    else:
        print('输入错误,请重新输入!')
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值