Python如何支持传入Content或Data对象初始化Movie类实例
方案1:__init__中做类型判断(完全匹配你的调用示例)
这个方案直接支持你期望的Movie(Content())/Movie(Data())调用方式,代码简洁直观:
class Movie: def __init__(self, obj): # 初始化所有字段默认值 self._title = "" self._url = "" self._year = 0 self._rating = 0.0 # 根据传入对象类型赋值对应属性 if isinstance(obj, Content): self._title = obj.title self._url = obj.url elif isinstance(obj, Data): self._title = obj.title self._year = obj.year self._rating = obj.rating else: raise TypeError("仅支持传入Content或Data类型的实例") # 按需添加property访问器 @property def title(self): return self._title @property def url(self): return self._url @property def year(self): return self._year @property def rating(self): return self._rating
- 优点:调用方式统一,符合你给出的使用示例,无需修改现有调用逻辑
- 缺点:后续新增支持的初始化类型时,需要修改__init__中的判断分支
方案2:@classmethod多构造器(更符合开闭原则)
你之前的类方法写法问题出在__init__的设计不合理,调整后实现如下:
class Movie: # 核心__init__接收所有属性参数,不耦合具体来源类型 def __init__(self, title="", url="", year=0, rating=0.0): self._title = title self._url = url self._year = year self._rating = rating # 从Content实例构造 @classmethod def from_content(cls, content): return cls( title=content.title, url=content.url ) # 从Data实例构造 @classmethod def from_data(cls, data): return cls( title=data.title, year=data.year, rating=data.rating ) # 同上添加property访问器,此处省略
调用方式为:
movie_content = Movie.from_content(Content()) movie_data = Movie.from_data(Data())
- 优点:拓展性极强,后续新增其他初始化来源时,只需新增对应的类方法即可,不需要修改现有__init__和已有的类方法逻辑,完全符合开闭原则,是公认的Pythonic多构造器实现。如果要匹配你原来的直接传实例的调用方式,也可以和方案1的逻辑结合,在__init__中判断传入参数的类型,自动调度对应的类方法即可。
同title数据合并方法
如果需要将同一个title对应的Content和Data数据合并到同一个Movie实例,可以额外添加合并方法:
def update_from_data(self, data): if data.title == self.title: self._year = data.year self._rating = data.rating # 使用示例 content = Content() data = Data() movie = Movie.from_content(content) movie.update_from_data(data)
内容的提问来源于stack exchange,提问作者Idan Perry
相关产品推荐
相关产品推荐

