【发布时间】:2017-11-29 15:12:46
【问题描述】:
我有一个保存数据的容器类。创建容器时,有不同的方法来传递数据。
- 传递包含数据的文件
- 直接通过参数传递数据
- 不传递数据;只需创建一个空容器
在 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 中,我看到了三个明显的解决方案,但没有一个是漂亮的:
A:使用关键字参数:
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 似乎是最好的,但用户必须知道他需要哪种方法。例如:如果他不知道args 是什么,他就不能做c = Container(args)。
什么是最 Pythonic 的解决方案?
【问题讨论】:
-
还有其他选择。 stackoverflow.com/questions/19305296/… 另外,我总是试图让我的代码满足我的需求,而不是围绕它们编写来让我的代码更纯粹。
-
虽然这里的所有答案都集中在提供解决方案上,但 Jörg W Mittag provides a very nice explanation 关于为什么函数重载在动态语言中没有意义。
标签: python constructor initialization initializer idioms