Python中将类属性按类别封装为其他类的写法是否符合Pythonic规范?
现有代码存在的错误
- 语法错误:
@property装饰的方法定义末尾缺少冒号,且重复定义了@bg.getter/@bd.getter,@property本身就已经声明了getter方法,重复定义属于冗余代码。 - 逻辑错误:property返回的是
Background/Border类本身,而非类的实例,你给self.bd.width赋值实际是给Border类添加了类属性,所有Main的实例会共享这些属性值,完全达不到每个实例独立存储属性的需求。 - 父类初始化错误:
super().__init__(self)写法错误,Python 3中调用父类构造方法不需要主动传入self,多余的self会导致父类初始化参数匹配失败。
符合Pythonic规范的实现方式
你的属性分组思路本身是合理的,当主类属性较多时按功能分组会比所有属性平铺开可读性高很多,是非常实用的写法,修正错误后的实现如下:
方案1:保留自定义分组类(适合分组需要额外方法的场景)
如果你的Background、Border后续需要加自定义方法,推荐用dataclasses简化数据类定义:
import somemodule as sm from dataclasses import dataclass # 数据类不需要手动写空__init__,会自动生成构造、打印等常用方法 @dataclass class Background: accent: str = "" color: str = "" @dataclass class Border: width: int = 0 color: str = "" class Main(sm.SomeClass): def __init__(self, item): # 修正父类初始化写法 super().__init__() self.item = item # 先初始化分组类的实例,绑定到私有属性上 self._bg = Background() self._bd = Border() # 赋值逻辑和你原来的写法完全一致 self.bd.width = 10 self.bd.color = 'blue' self.bg.accent = 'yellow' self.bg.color = 'green' @property def bg(self): # 返回提前初始化的实例 return self._bg @property def bd(self): return self._bd ins = Main('app')
方案2:用SimpleNamespace简化(仅做属性容器不需要额外方法的场景)
如果分组只是纯属性容器不需要加方法,可以不用单独定义类,直接用标准库的types.SimpleNamespace更简洁:
import somemodule as sm from types import SimpleNamespace class Main(sm.SomeClass): def __init__(self, item): super().__init__() self.item = item # 直接创建空的命名空间作为分组容器 self._bg = SimpleNamespace() self._bd = SimpleNamespace() self.bd.width = 10 self.bd.color = 'blue' self.bg.accent = 'yellow' self.bg.color = 'green' @property def bg(self): return self._bg @property def bd(self): return self._bd ins = Main('app')
如果你不需要限制用户修改分组本身(比如防止用户直接写self.bg = OtherObject替换整个分组对象),甚至不需要写property,直接在__init__里赋值self.bg = Background()即可,写法更简单。
内容的提问来源于stack exchange,提问作者Kuk1a
相关产品推荐
相关产品推荐

