1.__slots__控制属性访问
class MyClass:
__slots__ = ('attr1', 'attr2')
def __init__(self):
self.attr1 = 10
self.attr2 = 20
# 尝试添加不在 __slots__ 中的属性会报错
obj = MyClass()
obj.attr3 = 30 # 会引发 AttributeError
class Employee:
__slots__ = ('name', 'id', 'department')
def __init__(self, name, id, department):
self.name = name
self.id = id
self.department = department
# 创建多个员工实例,节省内存
employees = [Employee('John', 1, 'HR'), Employee('Alice', 2, 'Finance')]
# 数据类(dataclass):结合 __slots__ 可以更高效地定义具有固定属性的数据类。
from dataclasses import dataclass
@dataclass(slots=True)
class Point:
x: int
y: int
# 内存视图(memoryview):用于高效地操作内存缓冲区,可与 __slots__ 一起优化内存使用
import array
class MyArray:
__slots__ = ('data',)
def __init__(self):
self.data = array.array('i')
def append(self, value):
self.data.append(value)
arr = MyArray()
arr.append(1)
2.使用@property装饰器来实现属性的访问控制
class MyClass:
def __init__(self):
self._value = 0
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
if new_value >= 0:
self._value = new_value
else:
raise ValueError("Value must be non-negative")
obj = MyClass()
print(obj.value)
obj.value = 5
print(obj.value)
# 尝试设置负数值会引发 ValueError
# obj.value = -1
class Person:
def __init__(self, age):
self.age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not 0 <= value <= 120:
raise ValueError("Age must be between 0 and 120")
self._age = value
p = Person(11)
p.age = 22
3.使用描述符( Descriptor ):更高级的属性控制方式
class MyDescriptor:
def __get__(self, instance, owner):
print("Getting descriptor")
return "Default value"
def __set__(self, instance, value):
print(f"Setting descriptor to {value}")
class MyClass:
attribute = MyDescriptor()
my_instance = MyClass()
# 获取属性值,触发 __get__ 方法
print(my_instance.attribute)
# 设置属性值,触发 __set__ 方法
my_instance.attribute = "New value"
class ConfigValue:
def __init__(self, min_value, max_value):
self.min_value = min_value
self.max_value = max_value
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not self.min_value <= value <= self.max_value:
raise ValueError(f"Value must be between {self.min_value} and {self.max_value}")
instance.__dict__[self.name] = value
class Config:
temperature = ConfigValue(0, 100)
config = Config()
# 设置有效的值
config.temperature = 50
# 尝试设置无效的值,会触发异常
config.temperature = 150
4.元类( Metaclass ):在类创建时控制属性的定义
class Meta(type):
def __new__(cls, name, bases, attrs):
if 'special_attribute' not in attrs:
attrs['special_attribute'] = 'Default value'
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=Meta):
pass
class DescriptorMeta(type):
def __new__(cls, name, bases, attrs):
for key, value in attrs.items():
if hasattr(value, '__get__') and hasattr(value, '__set__'):
attrs[key] = value
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=DescriptorMeta):
attribute = MyDescriptor()