多个构造函数:Python方式?[重复]

发布于 2021-01-29 15:09:12

这个问题已经在这里有了答案

如何根据参数类型重载__init__方法? (10个答案)

3年前关闭。

我有一个保存数据的容器类。创建容器时,有不同的方法来传递数据。

  1. 传递包含数据的文件
  2. 通过参数直接传递数据
  3. 不要传递数据;只是创建一个空容器

在Java中,我将创建三个构造函数。如果在Python中可行,则如下所示:

class Container:

    def __init__(self):
        self.timestamp = 0
        self.data = []
        self.metadata = {}

    def __init__(self, file):
        f = file.open()
        self.timestamp = f.get_timestamp()
        self.data = f.get_data()
        self.metadata = f.get_metadata()

    def __init__(self, timestamp, data, metadata):
        self.timestamp = timestamp
        self.data = data
        self.metadata = metadata

在Python中,我看到了三个明显的解决方案,但是没有一个是漂亮的:

:使用关键字参数:

def __init__(self, **kwargs):
    if 'file' in kwargs:
        ...
    elif 'timestamp' in kwargs and 'data' in kwargs and 'metadata' in kwargs:
        ...
    else:
        ... create empty container

B :使用默认参数:

def __init__(self, file=None, timestamp=None, data=None, metadata=None):
    if file:
        ...
    elif timestamp and data and metadata:
        ...
    else:
        ... create empty container

C :仅提供构造函数以创建空容器。提供使用不同来源的数据填充容器的方法。

def __init__(self):
    self.timestamp = 0
    self.data = []
    self.metadata = {}

def add_data_from_file(file):
    ...

def add_data(timestamp, data, metadata):
    ...

解决方案A和B基本相同。我不喜欢if /
else,特别是因为我必须检查是否提供了此方法所需的所有参数。如果要通过第四种方法扩展代码以添加数据,则A比B灵活一些。

解决方案C似乎是最好的,但是用户必须知道他需要哪种方法。例如:c = Container(args)如果他不知道是什么,他就不能做args

什么是最Pythonic解决方案?

关注者
0
被浏览
86
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您不能在中使用多个具有相同名称的方法PythonJava不支持函数重载-与in不同。

    使用默认参数或**kwargs*args参数。

    您可以使用@staticmethod@classmethod装饰器制作静态方法或类方法,以返回类的实例,或添加其他构造函数。

    我建议你这样做:

    class F:
    
        def __init__(self, timestamp=0, data=None, metadata=None):
            self.timestamp = timestamp
            self.data = list() if data is None else data
            self.metadata = dict() if metadata is None else metadata
    
        @classmethod
        def from_file(cls, path):
           _file = cls.get_file(path)
           timestamp = _file.get_timestamp()
           data = _file.get_data()
           metadata = _file.get_metadata()       
           return cls(timestamp, data, metadata)
    
        @classmethod
        def from_metadata(cls, timestamp, data, metadata):
            return cls(timestamp, data, metadata)
    
        @staticmethod
        def get_file(path):
            # ...
            pass
    

    ⚠永远不要将可变类型作为python中的默认值。⚠看这里



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看