当前位置: 首页 > 面试题库 >

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

洪俊拔
2023-03-14
问题内容

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

如何根据参数类型重载__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解决方案?


问题答案:

您不能在中使用多个具有相同名称的方法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中的默认值。⚠看这里。



 类似资料:
  • 真的不可能在 dart 中为一个类创建多个构造函数吗? 在我的播放器类中,如果我有这个构造函数 然后我尝试添加这个构造函数: 我得到以下错误: 默认构造函数已定义。 我不是通过创建一个带有一堆非必需参数的构造函数来寻找解决方法。 有没有好办法解决这个问题?

  • 我需要避免重复的代码与这些构造函数,所以我想知道是否有一种方法来实例化这些变量只有一个?我看到了很多关于链接的帖子,但我还没有让它正常工作。

  • 我正在尝试修改类Circle以包含第三个构造函数,用于构造具有两个参数的Circle实例——半径的双精度和颜色的字符串。还修改主类以使用此构造函数构造Circle的实例。我对此有困难,我一直收到从未使用构造函数Circle的消息。请查看代码。

  • 在像 JavaScript 这种没有类的概念的语言中,如果想创建特定的实例对象,可以通过在函数之前加上 new 关键字来实现。在调用构造函数时可以传入参数以初始化实例对象的属性值。用这种方式创建的实例对象的属性和方法是独立的,不与其他实例对象共享。 在 JavaScript 中,构造函数一般长这样: function FamilyMember( name, age ) { this.name =

  • 我的问题是关于OOP(C)中的构造函数。当我在一个类中将默认构造函数定义为private,并且在main中将该类的一个对象初始化为default时,就会出现默认构造函数不可访问的错误。这很好。但我也在Public部分中使用默认参数构造函数,当我再次在main中初始化对象时,就会出现对函数重载的不明确调用。所以我的问题是,如果不能从main访问私有构造函数,那么编译器应该调用公共部分中的构造函数,这

  • 我通过各种站点了解java不支持多重继承。其中一个原因是为了避免像强制转换和构造函数链接这样的问题。多重继承如何导致Java中的强制转换和构造函数链接问题?有人能举例给我解释一下吗。