反射

反射

通过字符串来获取,设置,删除对象中的属性或方法

  1. 用户输入一串字符串,执行该字符串对应的方法
  2. hasattr() :判断一个属性是否在对象中,返回true或者False
  3. getattr() :通过字符串获取属性和方法,如果获取到了,就会返回相应的属性和方法
  4. setattr():通过字符串来设置属性和方法
  5. delatter():通过字符串来删除属性和方法
class Foo:
    def fun(self):
        print('run')
    def speak(self):
        print('speak')
p = Foo()

print(Foo.__dict__)#返回类的所有的方法{'__module__': '__main__', 'fun': <function Foo.fun at 0x0000014650AB7168>, 'speak': <function Foo.speak at 0x0000014650AB74C8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
cmd = input('请输入命令')
# 方案一
# 执行类中的方法
print(Foo.__dict__[cmd])#方法的内存地址
Foo.__dict__[cmd](p)
# 方案二
# 执行类中的方法
if hasattr(p,cmd):#判断一个属性是否在对象中,返回true或者False
    run = getattr(p,cmd)#run方法的内存地址# 通过字符串获取属性和方法,如果获取到了,就会返回相应的属性和方法
    run()
else:
    print('没有这个命令')

  1. setattr():通过字符串来设置属性和方法

    1. 放属性

      class Foo:
          def fun(self):
              print('run')
          def speak(self):
              print('speak')
      p = Foo()
      # 通过用户输入key和value往对象中赋值
      key = input('请输入key:')#qq
      value = input('请输入value:')#123
      setattr(p,key,value)
      print(p.__dict__)
      #{'qq': '123'}
      
    2. 放方法

      class Foo:
          def fun(self):
              print('run')
          def speak(self):
              print('speak')
      p = Foo()
      # 动态的往对象里面放方法
      def teat(a):
          print(a)
      print(p.__dict__)#{}
      
      setattr(p,'teat',teat)
      print(p.__dict__)#{'teat': <function teat at 0x000002968CC37168>}
      
      p.teat(11)#11
      
  2. delatter():通过字符串来删除属性和方法

    1. 原始的删除

      class Foo:
          def fun(self):
              print('run')
          def speak(self):
              print('speak')
      p = Foo()
      # 原始的删除
      p.name = 'czq'
      print(p.__dict__)#{'name': 'czq'}
      del p.name
      print(p.__dict__)#{}
      
      
    2. 动态删除p中的属性为变量a的属性

      class Foo:
          def fun(self):
              print('run')
          def speak(self):
              print('speak')
      p = Foo()
      p.name = 'czq'
      p.age = 18
      p.sex = 'male'
      print(p.__dict__)#{'name': 'czq', 'age': 18, 'sex': 'male'}
      a = input('请输入需要删除的属性:')#name
      delattr(p,a)
      print(p.__dict__)#{'age': 18, 'sex': 'male'}
      
      
      
      

用法

class BlackMedium:
    feature = 'Ugly'
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' % self.name)
    def rent_house(self):
        print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
b1=BlackMedium('玉皇大帝','回龙观')

# print(b1.__dict__)#对象的属性,{'name': '玉皇大帝', 'addr': '回龙观'}
# print(BlackMedium.__dict__)#类的方法,{'__module__': '__main__', 'feature': 'Ugly', '__init__': <function BlackMedium.__init__ at 0x0000012D3A3F7438>, 'sell_house': <function BlackMedium.sell_house at 0x0000012D3A3F7558>, 'rent_house': <function BlackMedium.rent_house at 0x0000012D3A3F75E8>, '__dict__': <attribute '__dict__' of 'BlackMedium' objects>, '__weakref__': <attribute '__weakref__' of 'BlackMedium' objects>, '__doc__': None}

方法一

print(hasattr(b1,'sell_house'))#True,sell_house是对象的方法
a = 'sell_house'
getattr(b1,a)()#玉皇大帝 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼

方法二

sell_house = getattr(b1,a)
sell_house()#玉皇大帝 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼

name = getattr(b1,'name')
print(name)#玉皇大帝

删除属性和方法

print(b1.__dict__)#{'name': '玉皇大帝', 'addr': '回龙观'}

delattr(b1,'name')
print(b1.__dict__)#{'addr': '回龙观'}


使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,# 如果有就执行,没有,就报错

#utils.py

#别人写的,领导规定要写speak,run,eat方法
#这个人没写完
def speak():
    print('speak')


def run():
    print('run')
#这个人写完了
def eat():
    print('eat')

import utils

utils.speak()
if hasattr(utils,'speak'):
    speak=getattr(utils,'speak')
    speak()

# 我以为它写完了
utils.eat()
# 更安全
if hasattr(utils,'eat'):
    eat=getattr(utils,'eat')
    eat()
else:
    print('那个人还没写完呢')

posted @ 2019-09-03 18:10  豆瓣酱瓣豆  阅读(84)  评论(0编辑  收藏  举报