全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 8 分钟 ✍️ juanwangdev

Python属性动态管理

Python允许动态添加、修改、删除对象属性,这是元编程的基础能力。

dict 属性字典

Python
class Person:
    def __init__(self, name):
        self.name = name

p = Person("Alice")

# __dict__ 存储实例属性
print(p.__dict__)          # {'name': 'Alice'}

# 直接修改 __dict__
p.__dict__['age'] = 30
print(p.age)               # 30

# 动态添加属性
p.email = "alice@example.com"
print(p.__dict__)          # {'name': 'Alice', 'age': 30, 'email': 'alice@example.com'}
Python
# 类的 __dict__
print(Person.__dict__.keys())
# 包含:__init__, __module__, __dict__, __weakref__ 等

# __dict__ 是 mappingproxy(只读视图)
print(type(Person.__dict__))  # <class 'mappingproxy'>
# Person.__dict__['new_attr'] = 1  # TypeError

setattr、getattr、delattr

Python
class Dynamic:
    pass

obj = Dynamic()

# setattr(obj, name, value)
setattr(obj, 'x', 10)
setattr(obj, 'y', 20)
print(obj.x, obj.y)        # 10 20

# getattr(obj, name, default)
print(getattr(obj, 'x'))           # 10
print(getattr(obj, 'z', None))     # None(带默认值)
# getattr(obj, 'z')                # AttributeError

# hasattr(obj, name)
print(hasattr(obj, 'x'))           # True
print(hasattr(obj, 'z'))           # False

# delattr(obj, name)
delattr(obj, 'x')
print(hasattr(obj, 'x'))           # False
Python
# 批量动态属性设置
def set_attributes(obj, attrs_dict):
    for name, value in attrs_dict.items():
        setattr(obj, name, value)

class Config:
    pass

config = Config()
set_attributes(config, {
    'host': 'localhost',
    'port': 8080,
    'debug': True
})

print(config.host, config.port)  # localhost 8080

setattrdelattr

Python
class Validated:
    "带验证的属性设置"

    def __setattr__(self, name, value):
        # 验证逻辑
        if name == 'age' and value < 0:
            raise ValueError("age cannot be negative")
        if name == 'name' and not isinstance(value, str):
            raise TypeError("name must be string")

        # 存储到 __dict__(避免无限递归)
        self.__dict__[name] = value

    def __delattr__(self, name):
        if name == 'id':
            raise AttributeError("id cannot be deleted")
        del self.__dict__[name]

v = Validated()
v.name = "Alice"
v.age = 30

# v.age = -1        # ValueError
# v.name = 123      # TypeError

del v.age
# del v.id          # AttributeError(需要先定义id)

注意:在__setattr__中使用self.attr = value会导致无限递归,必须直接操作__dict__

getattrgetattribute

Python
class LazyAttributes:
    "延迟加载属性"

    _data = {
        'config1': 'value1',
        'config2': 'value2',
    }

    def __getattr__(self, name):
        "仅在属性不存在时调用"
        if name in self._data:
            print(f"Loading {name}...")
            return self._data[name]
        raise AttributeError(f"No attribute '{name}'")

obj = LazyAttributes()
print(obj.config1)      # Loading config1... value1
print(obj.config1)      # value1(第二次直接返回,已缓存?不,未缓存)

# 添加到 __dict__ 后不再触发 __getattr__
obj.config1 = "cached"
print(obj.config1)      # cached(不触发 __getattr__)
Python
class InterceptAll:
    "拦截所有属性访问"

    def __getattribute__(self, name):
        print(f"Accessing: {name}")
        # 必须用 super() 避免递归
        return super().__getattribute__(name)

    def __getattr__(self, name):
        print(f"Missing: {name}")
        return f"default_{name}"

obj = InterceptAll()
obj.x = 10
print(obj.x)     # Accessing: x → 10
print(obj.y)     # Accessing: y → Missing: y → default_y

动态方法添加

Python
class DynamicClass:
    pass

# 添加实例方法
def greet(self, name):
    return f"Hello, {name}! I'm {self.name}"

obj = DynamicClass()
obj.name = "Dynamic"

import types
obj.greet = types.MethodType(greet, obj)
print(obj.greet("World"))  # Hello, World! I'm Dynamic

# 添加到类(所有实例共享)
DynamicClass.greet = greet
obj2 = DynamicClass()
obj2.name = "Another"
print(obj2.greet("User"))  # Hello, User! I'm Another

属性代理模式

Python
class Proxy:
    "属性代理"

    def __init__(self, target):
        self._target = target

    def __getattr__(self, name):
        # 转发到目标对象
        return getattr(self._target, name)

    def __setattr__(self, name, value):
        if name == '_target':
            # 特殊属性直接存储
            super().__setattr__(name, value)
        else:
            # 其他属性转发
            setattr(self._target, name, value)

class RealObject:
    def __init__(self):
        self.data = "original"

real = RealObject()
proxy = Proxy(real)

print(proxy.data)     # original
proxy.data = "proxied"
print(real.data)      # proxied(目标对象也被修改)

slots 限制动态属性

Python
class Restricted:
    "限制动态属性"

    __slots__ = ['name', 'age']

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

obj = Restricted("Alice", 30)
print(obj.name)        # Alice

# obj.email = "test"   # AttributeError
# obj.__dict__         # AttributeError(无 __dict__)

# 优点:内存效率更高,属性访问更快
# 缺点:无法动态添加属性,无法使用 __dict__

要点总结

  1. **__dict__**存储实例属性,类属性存储在类的__dict__
  2. **setattr/getattr/delattr**是动态属性操作的内置函数
  3. **__setattr__**拦截属性设置,必须操作__dict__避免递归
  4. **__getattr__处理缺失属性,__getattribute__**拦截所有访问
  5. **__slots__**限制动态属性,提升内存效率

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python动态类创建
下一篇 → Python自定义元类
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库