我有一个包含数据的容器类。创建容器时,有不同的方法来传递数据。
在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)
。
什么是最具Python性的解决方案?
在
Python
中不能有多个同名的方法。不支持函数重载(与Java
中不同)。使用默认参数或
**kwargs
和*args
参数。您可以使用
@staticmethod
或@classmethod
装饰符生成静态方法或类方法,以返回类的实例或添加其他构造函数。我建议你做:
不能有多个构造函数,但可以有多个名称恰当的工厂方法。
但是,您不能轻易地阻止用户直接使用构造函数。(如果这很重要,作为开发过程中的安全预防措施,您可以在构造函数中分析调用堆栈,并检查调用是否由预期的方法之一进行。)
大多数Pythonic将是Python标准库已经做的事情。核心开发人员Raymond Hettinger(这个
collections
家伙)gave a talk on this,以及如何编写类的一般准则。使用单独的类级函数初始化实例,比如
dict.fromkeys()
不是类初始值设定项,但仍然返回dict
的实例。这允许您灵活地处理所需的参数,而不必在需求更改时更改方法签名。相关问题 更多 >
编程相关推荐