python面向对象之反射

  反射:通过字符串操作对象的相关属性。

  虽然eval也可以这样操作,但是通过反射操作安全性更强。

  1,getattr

class Person:
    kind = '人科'

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

    def speak(self):
        print('我叫%s' %self.name)


person = Person('zxc', 26)
print(getattr(person, 'name'))  # zxc      getattr(object, 字符串名字)就可以直接调用对象的对应属性
print(getattr(Person, 'kind'))  # 人科
# print(getattr(Person, 'name'))  # 报错  Person类中没有name属性  对象中如果没有对应的名字getattr就会报错
func = getattr(person, 'speak')  # 获取对象的方法的内存地址
func()  # 我叫zxc   加括号就可以实现方法的调用  也可以getattr(person, 'speak')()直接调用

   2,hasattr

# hasattr 一般和getattr同时使用,用于判断对象中是否有这个名字
if hasattr(person, 'speak'):  # 先判断是否有这个名字,有的话在使用getattr调用
    getattr(person, 'speak')()  # 我叫zxc
print(hasattr(Person, 'name'))  # False

   反射在模块中的应用。

# 在python中一切皆对象,所以也可以反射模块
import time
print(getattr(time, 'time')())  # 1516603939.79633
# 反射的模块的带参数
print(getattr(time, 'strftime')('%Y-%m-%d %H:%M:%S'))  # 2018-01-22 15:13:51

# 反射自身模块
def func():
    print('this is func')

import sys
# 在自身模块中sys.modules字典中键'__main__'的值就是自身模块
getattr(sys.modules['__main__'], 'func')()  # this is func
# 因为键'__main__'的值是变化的量,在其他模块调用时,键'__main__'的值就是其他模块。因此这里可以改为__name__
getattr(sys.modules[__name__], 'func')()  # this is func

   3,setattr 通过字符串修改对象的属性 不常用

class Person:
    kind = '人科'

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

    def speak(self):
        print('我叫%s' %self.name)

person = Person('zxc', 26)
print(person.name)  # zxc
setattr(person, 'name', 'zzy')
print(person.name)  # zzy

   4,delattr 通过字符串删除对象的属性 不常用

class Person:
    kind = '人科'

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

    def speak(self):
        print('我叫%s' %self.name)

person = Person('zxc', 26)
print(person.__dict__)  # {'name': 'zxc', 'age': 26}
delattr(person, 'age')
print(person.__dict__)  # {'name': 'zxc'}
原文地址:https://www.cnblogs.com/zxc-Weblog/p/8329900.html