我有一个名为Portfolio& amp;现在我有2个构造函数(虽然我刚刚发现你在python中无法重载函数)所以我必须合并这两个构造函数。
我是一名经验丰富的python程序员,但这两个非常矛盾的合并构造函数确实是我的头脑! :P
第一个构造函数:
+目的是创建一个.db文件&初始化类变量
- 初始化类成员变量
- 检查具有路径和名称db_path的文件是否存在:如果存在,我们退出coz我们不想覆盖现有数据库,因此我们返回无
- 我们创建数据库(sql数据库)&设置必要的表格
- 导入投资组合数据(创建日期等)
第二个构造函数:
+目的是从现有的sql数据库文件导入所有库存数据&初始化变量
- 初始化类成员变量
- 检查具有路径和名称db_path的文件是否存在:如果不存在,我们退出coz,我们不想覆盖现有数据库,因此我们返回无
- 我们将该函数称为从数据库中导入所有股票
- 导入投资组合数据(创建日期等)
如何合并这两个构造函数,呃,为什么python不允许重载
class Portfolio:
""" Portfolio class implementation """
# Class Variables:
# self.db_path
# self.app_parent
# self.tracking_stocks
# self.registered_stocks
# self.total_purchase_exp
# self.ytd_roi
# self.cash_reserve
# Class Functions:
def __init__( self, _app_parent, _db_path, stock_list ):
""" Constructor: """
self.db_path = _db_path
self.app_parent = _app_parent
self.tracking_stocks = []
self.registered_stocks = []
self.total_purchase_exp = 0
self.ytd_roi = 0
self.cash_reserve = 500
if database_exists( self.db_path ):
return None
self.create_database()
self.import_portfolio_data()
for stock_data in stock_list:
self.add_stock( stock_data )
def __init__( self, _app_parent, _db_path ):
""" Constructor: """
self.db_path = _db_path
self.app_parent = _app_parent
self.tracking_stocks = []
self.registered_stocks = []
self.total_purchase_exp = 0
self.ytd_roi = 0
self.cash_reserve = 500
if not self.database_exists( self.db_path ):
return None
self.import_portfolio_data()
self.import_stocks()
答案 0 :(得分:2)
答案 1 :(得分:1)
def __init__(self, _app_parent, _db_path, stock_list=None):
self.db_path = _db_path
self.app_parent = _app_parent
self.tracking_stocks = []
self.registered_stocks = []
self.total_purchase_exp = 0
self.ytd_roi = 0
self.cash_reserve = 500
if stock_list:
if database_exists( self.db_path ):
return None
self.create_database()
self.import_portfolio_data()
for stock_data in stock_list:
self.add_stock( stock_data )
else:
if not self.database_exists( self.db_path ):
return None
self.import_portfolio_data()
self.import_stocks()
大多数都是复制粘贴的,所以我无法证明缩进的准确性等,但这是在Python中创建通用__init__
方法的一般模式(注意{{1本身不是构造函数,它是一个初始化器)。由于Python支持关键字args和关键字args的默认值,因此没有理由使用重载(实际上,我们通过不进行重载来节省大量重复代码)。相反,我们只使用关键字arg stock_list,默认值为None。
这也没有完全修复;一些问题仍然存在(因为它是复制粘贴的)。我不知道构造函数的细节,但我认为通过更多的重构,你可以设置__init__
更短更优雅的东西(考虑将初始化的部分分成几部分)方法,如__init__
,并调用来自_init_db()
的方法。
答案 2 :(得分:1)
我会使用class methods来处理不同的情况。这实际上是适用于Python的C++ Named Constructor习语的变体。您可以调用类方法来根据需要创建实例,而不是调用构造函数目录。以下是我对此进行编码的方法:
class Portfolio:
def __init__(self, app_parent, db_path):
"""Create a fully initialized and empty instance."""
self.db_path = db_path
self.app_parent = app_parent
self.tracking_stocks = []
self.registered_stocks = []
self.total_purchase_exp = 0
self.ytd_roi = 0
self.cash_reserve = 500
@classmethod
def new_database(cls, app_parent, db_path, stock_list):
"""Create a Portfolio instance wrapped around a new database and
initialize it with ``stock_list``. If a database already exists at
``db_path``, then an exception is thrown."""
instance = cls(app_parent, db_path)
if database_exists(instance.db_path):
raise Exception('Database already exists at '+instance.db_path)
instance.create_database()
instance.import_portfolio_data()
for stock_data in stock_list:
instance.add_stock(stock_data)
return instance
@classmethod
def from_database(cls, app_parent, db_path):
"""Create a Portfolio instance from the database located at
``db_path``. If the database does not exist, then an exception
is thrown."""
instance = cls(app_parent, db_path)
if not database_exists(instance.db_path):
raise Exception('Database does not exist at '+instance.db_path)
instance.import_portfolio_data()
instance.import_stocks()
return instance
用法很简单:
new_portfolio = Portfolio.new_database('/data/port.db')
existing_portfolio = Portfolio.from_database('/data/port.db')
从可用性和可维护性的角度来看,有一些非常重要的事情。首先,使用类实例参数(cls
)在命名构造函数而不是类中创建新实例。我可以使用instance = cls(...)
而不是instance = Portfolio(...)
。如果向Portfolio
添加子类并调用其中一个类方法,则会中断。
第二个(也可能更重要)一点是,您应该使用异常而不是在出现错误时返回None
。它更像 pythonic ,一般来说更安全。