面向对象魔术方法

发布时间 2023-09-14 09:46:01作者: 岳宗柯

1.__setattr__如何使用

setattr 是 Python 中的一个特殊方法(魔术方法),用于自定义对象的属性赋值操作。当您尝试设置对象的属性时,Python 会自动调用 setattr 方法,允许您在属性赋值时添加自定义逻辑。这个方法可以用于数据验证、计算、记录属性更改等操作。

以下是如何使用 setattr 方法的示例:

class MyClass:
    def __init__(self, x):
        self.x = x

    def __setattr__(self, name, value):
        if name == 'x':
            if value < 0:
                raise ValueError("x cannot be negative")
        # 使用 super() 避免无限递归
        super().__setattr__(name, value)

obj = MyClass(10)
print(obj.x)  # 输出 10

# 尝试设置 x 为负数,触发异常
try:
    obj.x = -5
except ValueError as e:
    print(e)  # 输出 "x cannot be negative"

在上面的示例中,我们定义了一个 MyClass 类,该类具有一个属性 x。在 setattr 方法中,我们添加了一个自定义检查,如果尝试将 x 设置为负数,则会引发 ValueError 异常。

注意以下几点:

setattr 方法中,我们首先检查属性的名称是否为 'x',然后检查属性值是否小于 0。
我们使用 super().setattr(name, value) 来实际设置属性的值。这是因为直接在 setattr 方法中调用 self.x = value 会导致无限递归调用 setattr
使用 setattr 方法可以允许您在属性设置时执行自定义逻辑,例如数据验证、属性更改记录、计算相关属性等。这对于确保对象的属性处于一致的状态非常有用。然而,要小心使用它,以避免无限递归或使代码变得复杂。

2.__dict__如何使用

dict 是 Python 中用于访问对象的属性字典的特殊属性。这个属性是一个包含对象的所有属性和它们的值的字典,可以用于查看和修改对象的属性。

以下是如何使用 dict 属性的示例:

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

obj = MyClass(10, 20)

# 访问对象的属性字典
print(obj.__dict__)
# 输出:{'x': 10, 'y': 20}

# 添加新属性
obj.__dict__['z'] = 30
print(obj.z)  # 输出 30

# 修改属性值
obj.__dict__['x'] = 100
print(obj.x)  # 输出 100

# 删除属性
del obj.__dict__['y']
print(obj.__dict__)
# 输出:{'x': 100, 'z': 30}

需要注意以下几点:

dict 属性返回一个字典,其中包含了对象的属性名作为键和属性值作为值。
您可以使用 obj.dict[key] 来访问属性值,其中 key 是属性名。
您也可以使用 obj.dict[key] = value 来添加新属性或修改属性的值。
使用 del obj.dict[key] 可以删除属性。
尽管 dict 属性提供了一种动态操作对象属性的方式,但通常情况下,直接访问对象的属性(例如 obj.x)或使用属性访问器(例如 getattr(obj, 'x') 和 setattr(obj, 'x', value))更加推荐,因为它们更符合 Python 的习惯用法并提供更好的可读性。

使用 dict 属性时需要格外小心,因为它绕过了属性的 getter 和 setter 方法,可能导致意外的行为或破坏封装性。一般来说,最好避免直接操作 dict,而是使用属性访问器和属性定义来管理对象的属性。