You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python类实例化时自动生成属性的Getter和Setter方法

问题

我有一个包含Tensor的类,该类的属性列表无法预先确定。我希望在类实例化时,根据传入的属性名称列表自动生成对应属性的Getter和Setter方法。示例代码如下:

from typing import List, Dict, Optional
import torch

class Items:
    def __init__(
        self,
        names: List[str]
    ):
        #: 待生成的属性名称
        self.names: List[str] = names
        #: 所使用的Tensor
        self.tensors: Dict[str, torch.Tensor] = {}
        
    def get_tensor(self, name: str) -> Optional[torch.Tensor]:
        return self.tensors.get(name)
        
    def set_tensor(self, name: str, tensor: torch.Tensor):
        self.tensors[name] = tensor

    # 需要为多个属性生成完全相同的Setter和Getter函数:
    # entries、classes、scores、target_classes、target_scores、embeddings、heatmaps、losses...
    # 该列表在实例化时由self.names提供
    
    @property
    def entries(self) -> Optional[torch.Tensor]:
        return self.get_tensor("entries")
        
    @entries.setter
    def entries(self, tensor: torch.Tensor):
        self.set_tensor("entries", tensor)
解决方案

你可以在__init__方法中遍历传入的属性名称列表,利用Python的property类动态生成对应的Getter和Setter,并绑定到实例上,代码实现如下:

from typing import List, Dict, Optional
import torch

class Items:
    def __init__(self, names: List[str]):
        self.names = names
        self.tensors: Dict[str, torch.Tensor] = {}
        
        # 为每个名称动态生成属性
        for name in names:
            # 定义Getter
            def get_prop(self, attr_name=name):
                return self.get_tensor(attr_name)
            
            # 定义Setter
            def set_prop(self, tensor, attr_name=name):
                self.set_tensor(attr_name, tensor)
            
            # 将property绑定到实例
            setattr(self, name, property(get_prop, set_prop))
        
    def get_tensor(self, name: str) -> Optional[torch.Tensor]:
        return self.tensors.get(name)
        
    def set_tensor(self, name: str, tensor: torch.Tensor):
        self.tensors[name] = tensor

关键说明

  • 给get_prop和set_prop添加attr_name=name作为默认参数,是为了避免闭包的延迟绑定问题——如果不这么做,所有生成的方法都会引用循环最后一个name的值。
  • 使用setattr将动态创建的property对象绑定到实例,这样每个传入的名称都会成为实例的可读写属性。
  • 使用示例:
    # 实例化时指定需要的属性
    items = Items(["entries", "classes", "scores"])
    
    # 设置属性值
    items.entries = torch.tensor([1,2,3])
    
    # 获取属性值
    print(items.entries)  # 输出 tensor([1, 2, 3])
    print(items.scores)   # 未设置时返回 None
    

注意:如果属性名称包含空格(如"target classes"),需要先将其转换为合法的Python标识符(比如target_classes),否则无法直接作为属性名使用。如果必须保留原名称,可以通过重写__getattr__和__setattr__方法实现,但这种方式不如直接生成属性直观。

内容的提问来源于stack exchange,提问作者Xiiryo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:45:42