博客
关于我
python getattrribute_Python学习——面向对象高级之反射
阅读量:796 次
发布时间:2023-03-05

本文共 3657 字,大约阅读时间需要 12 分钟。

反射是Python中的一个强大工具,用于动态操作对象及其属性。它通过四个内置函数:hasattrgetattrsetattrdelattr 操作对象,实现对对象属性的查询、获取、设置和删除。这些函数在模块和函数的反射中同样发挥重要作用。

hasattr

hasattr(object, name) 用于判断对象 object 是否包含名为 name 的属性。其工作原理是调用 getattr(object, name),若抛出 AttributeError,则返回 False,否则返回 True。例如:

class Person(object):    def __init__(self, name):        self.name = name    def talk(self):        print('%s正在交谈' % self.name)p = Person('laowang')print(hasattr(p, 'talk'))  # 输出 Trueprint(hasattr(p, 'name'))  # 输出 Trueprint(hasattr(p, 'abc'))  # 输出 False

getattr

getattr(object, name, default=None) 用于获取对象 object 中的属性或方法,并返回其值。如果属性不存在,且提供了默认值,则返回默认值。例如:

class Person(object):    def __init__(self, name):        self.name = name    def talk(self):        print('%s正在交谈' % self.name)p = Person('laowang')name = getattr(p, 'name')  # 获取 name 属性的值talk_func = getattr(p, 'talk')  # 获取 talk 方法talk_func()  # 调用 talk 方法# 若属性不存在,提供默认值s = getattr(p, 'abc', 'not find')  # 输出 'not find'

setattr

setattr(object, name, value) 用于为对象 object 添加或修改属性。例如:

class Person(object):    def __init__(self, name):        self.name = namep = Person('laowang')setattr(p, 'talk', lambda self: print('%s正在交谈' % self.name))  # 添加 talk 方法setattr(p, 'age', 30)  # 添加 age 属性print(p.age)  # 输出 30

delattr

delattr(object, name) 用于删除对象 object 中的属性。需要注意的是,它不能用于删除方法。例如:

class Foo(object):    country = 'china'    def __init__(self, name):        self.name = nameobj = Foo('abc')delattr(obj, 'name')  # 删除 name 属性print(getattr(obj, 'name'))  # 输出 AttributeError: 'Foo' object has no attribute 'name'delattr(Foo, 'country')  # 删除 country 静态属性print(getattr(Foo, 'country'))  # 输出 AttributeError: 'Foo' object has no attribute 'country'

模块与函数反射

由于 Python 中一切皆对象,模块和函数也可以使用反射机制。例如:

import module_test as objprint(hasattr(obj, 'test'))  # 输出 Truegetattr(obj, 'test')()  # 输出 'from the test'

对象魔术方法

对象的某些方法可以通过重定义魔术方法(如 __getattr____setattr____delattr__ 等)来自定义行为。例如:

class Foo:    def __init__(self, x):        self.x = x    def __getattr__(self, item):        print('----> 从 getattr: 你找的属性不存在')    def __setattr__(self, key, value):        print('----> 从 setattr: 这是尝试设置属性')        self.__dict__[key] = value    def __delattr__(self, item):        print('----> 从 delattr: 这是尝试删除属性')        self.__dict__.pop(item)f1 = Foo(10)print(f1.__dict__)  # 输出 {'x': 10}f1.z = 3print(f1.__dict__)  # 输出 {'x': 10}del f1.aprint(f1.__dict__)  # 输出 {'x': 10}

strrepr

__str__ 方法返回用户看到的字符串,__repr__ 返回开发者看到的字符串。例如:

class Student(object):    def __init__(self, name):        self.name = name    def __str__(self):        return 'Student object (name: %s)' % self.name    __repr__ = __str__s = Student('Michael')print(str(s))  # 输出 'Student object (name: Michael)'print(repr(s))  # 输出 'Student object (name: Michael)'

迭代器协议

要使类可以用于 for 循环,需实现 __iter____next__ 方法。例如:

class Fib(object):    def __init__(self):        self.a, self.b = 0, 1    def __iter__(self):        return self    def __next__(self):        self.a, self.b = self.b, self.a + self.b        if self.a > 100000:            raise StopIteration()        return self.afor n in Fib():    print(n)

call 方法

任何类可以通过定义 __call__ 方法使实例可调用。例如:

class Student(object):    def __init__(self, name):        self.name = name    def __call__(self):        print('My name is %s.' % self.name)s = Student('Michael')s()  # 输出 'My name is Michael.'

slots

__slots__ 用于优化内存使用,限制实例属性仅包含指定字段。例如:

class Foo(object):    __slots__ = ['name', 'age']f1 = Foo()f1.name = 'alex'f1.age = 18print(f1.__slots__)  # 输出 ['name', 'age']f2 = Foo()f2.name = 'egon'f2.age = 19print(f2.__slots__)  # 输出 ['name', 'age']print(Foo.__dict__)  # 输出 {}

结论

反射机制在 Python 中非常强大,可以用于动态操作对象属性、模块和函数,以及自定义对象行为。通过合理使用这些功能,可以简化代码,并提高开发效率。

转载地址:http://vxafk.baihongyu.com/

你可能感兴趣的文章