Python实例化类时property setter未生效 坐标未转Atom对象
问题根源
Molecule类的__init__方法直接对私有属性self.__coordinates赋值,跳过了coordinates属性绑定的setter转换逻辑:
- 实例化时传入坐标参数:原始列表直接存入私有属性,完全不执行格式校验、Atom实例生成的逻辑
- 实例化完成后手动给
coordinates属性赋值:才会触发setter方法,走完校验、转换流程,因此只有这种场景能得到正确的Atom对象列表。
修复方案
只需要调整两处代码即可:
- 初始化方法中不要直接操作私有属性,改为给
self.coordinates赋值,复用setter的转换逻辑,保证两种赋值场景走同一套处理流程 - 给setter方法增加
None值兼容处理,适配初始化时不传坐标的默认场景,避免传入None时触发列表深度校验报错。
修改后的核心代码
class Molecule(object): def __init__(self, coordinates=None): # 改为调用属性setter赋值,而非直接操作私有属性 self.coordinates = coordinates self.nelec = None self.Z = None self.natom = None @property def coordinates(self): return self.__coordinates @coordinates.setter def coordinates(self, coords: list): # 兼容空分子初始化的None场景 if coords is None: self.__coordinates = None return depth = lambda l: isinstance(l, list) and max(map(depth, l)) + 1 if depth(coords) != 2: raise Exception("Coordinates must be provided as a nested list of depth 2") else: atom_list = [] for atom_coord in coords: # 原调试用print("Test")可按需删除 atom_coord = self.__check_coord(atom_coord) atom_label, atom_vec = atom_coord[0], atom_coord[1:] atom_list.append(Atom(atom_label, atom_vec)) self.__coordinates = atom_list @staticmethod def __check_coord(coord): isnumber = lambda x: (type(x) == float or type(x) == int) if type(coord[0]) != str: raise Exception("First element must a string for an atomic label") if len(list(filter(isnumber, coord))) != 3 and len(coord) != 4: raise Exception("Each coordinate must be a list of length 4 with 1 string and 3 numbers") coord[0] = coord[0].upper() return coord
验证效果
修改后两种赋值方式表现完全一致:
>>> mol = Molecule([['H', 0, 1, 1], ['O', -1, 0, 0], ['H', -1, 0, 1]]) >>> mol.coordinates [<__main__.Atom object at 0x10c62c850>, <__main__.Atom object at 0x10c62c640>, <__main__.Atom object at 0x10c62c910>] >>> mol2 = Molecule() >>> mol2.coordinates =[['H', 0, 1, 1], ['O', -1, 0, 0], ['H', -1, 0, 1]] >>> mol2.coordinates [<__main__.Atom object at 0x10c62c970>, <__main__.Atom object at 0x10c62ca30>, <__main__.Atom object at 0x10c62caf0>]
内容的提问来源于stack exchange,提问作者Kyle
相关产品推荐
相关产品推荐

